diff options
| -rw-r--r-- | routes/lightning/conversionFee.js | 12 | ||||
| -rw-r--r-- | routes/lightning/receive.js | 4 | ||||
| -rw-r--r-- | routes/lnurl.js | 52 |
3 files changed, 66 insertions, 2 deletions
diff --git a/routes/lightning/conversionFee.js b/routes/lightning/conversionFee.js new file mode 100644 index 00000000..8fca9b0f --- /dev/null +++ b/routes/lightning/conversionFee.js @@ -0,0 +1,12 @@ +// Code for the conversion fee +// This is in a separate file so that the same function can be used by ./send and ./receive + +const conversionFeeMultiplier = 0.00; +const conversionFeeReceiver = "coinosfees"; // account that receives the fees + +/** + * Returns the fee you have to pay for withdrawing 'amount' lightning BTC. + */ +function computeConversionFee(amount) { + return Math.floor(amount * conversionFeeMultiplier); +} diff --git a/routes/lightning/receive.js b/routes/lightning/receive.js index 6723d577..6d10eb9b 100644 --- a/routes/lightning/receive.js +++ b/routes/lightning/receive.js @@ -1,3 +1,5 @@ +const { computeConversionFee } = require('./conversionFee.js'); + const handlePayment = async (msg) => { l.info("incoming lightning payment", msg.value, msg.payment_request, msg.settled); if (!msg.settled) return; @@ -60,6 +62,8 @@ const handlePayment = async (msg) => { invoice.received += total; await account.increment({ balance: total }, { transaction }); + // get the # of fee credits you would need to pay off this amount of bitcoin + await account.increment({ btc_credits: computeConversionFee(total) }, { transaction }); await account.reload({ transaction }); await invoice.save({ transaction }); await payment.save({ transaction }); diff --git a/routes/lnurl.js b/routes/lnurl.js index 0466e143..49212330 100644 --- a/routes/lnurl.js +++ b/routes/lnurl.js @@ -12,6 +12,8 @@ withdrawals = persist("data/withdrawals.json"); lnurlServer = lnurl.createServer(config.lnurl); +let { computeConversionFee, conversionFeeReceiver } = require('lightning/conversionFee.js'); + var optionalAuth = function(req, res, next) { passport.authenticate("jwt", { session: false }, function(err, user, info) { req.user = user; @@ -391,6 +393,7 @@ lnurlServer.bindToHook( try { let decoded = await lnp.decodePayReq({ pay_req: pr }); let amount = decoded.num_satoshis; + let conversionFee = computeConversionFee(amount); await db.transaction(async transaction => { let account = await db.Account.findOne({ @@ -402,8 +405,52 @@ lnurlServer.bindToHook( transaction }); + // account that receives conversion fees + let receiverAccount = await db.Account.findOne({ + where: { + "$user.username$": conversionFeeReceiver + }, + include: [ + { + model: db.User, + as: "user" + }, + ], + lock: transaction.LOCK.UPDATE, + transaction + }); + if (account.balance < amount) { throw new Error("Insufficient funds"); + } else if (account.balance < amount + conversionFee) { + throw new Error("Insufficient funds for conversion fee"); + } + + // use user's credits to reduce fee, if available + let conversionFeeDeduction = Math.min(account.lightning_credits, conversionFee); + if (conversionFeeDeduction) { + await account.decrement({ lightning_credits: conversionFeeDeduction }, { transaction }); + await account.reload({ transaction }); + conversionFee -= conversionFeeDeduction; + } + + let fee_payment_id = null; + if (conversionFee) { + await receiverAccount.increment({ balance: conversionFee }, { transaction }); + await receiverAccount.reload({ transaction }); + let fee_payment = await db.Payment.create({ + amount: conversionFee, + fee: 0, + memo: "Bitcoin conversion fee", + account_id: receiverAccount.id, + user_id: receiverAccount.user_id, + rate: app.get("rates")[receiverAccount.user.currency], + currency: receiverAccount.user.currency, + confirmed: true, + received: true, + network: "COINOS" + }, { transaction }); + fee_payment_id = fee_payment.id; } let payment = await db.Payment.create( @@ -415,7 +462,8 @@ lnurlServer.bindToHook( rate: app.get("rates")[user.currency], currency: user.currency, confirmed: true, - network: "lightning" + network: "lightning", + fee_payment_id: fee_payment_id }, { transaction } ); @@ -447,7 +495,7 @@ lnurlServer.bindToHook( } }, 1000); - await account.decrement({ balance: amount }, { transaction }); + await account.decrement({ balance: (amount + conversionFee) }, { transaction }); await account.reload({ transaction }); let p = payment.get({ plain: true }); |
