stacker.news/pages/api/lnwith.js

82 lines
2.8 KiB
JavaScript

// verify k1 exists
// send back
import models from '../../api/models'
import { datePivot } from '../../lib/time'
import lnd from '../../api/lnd'
import { createWithdrawal } from '../../api/resolvers/wallet'
export default async ({ query, headers }, res) => {
if (!query.k1) {
return res.status(400).json({ status: 'ERROR', reason: 'k1 not provided' })
}
if (query.pr) {
try {
return await doWithdrawal(query, res, headers)
} catch (e) {
return res.status(400).json({ status: 'ERROR', reason: e.message })
}
}
let reason
try {
const lnwith = await models.lnWith.findFirst({
where: {
k1: query.k1,
createdAt: {
gt: datePivot(new Date(), { hours: -1 })
}
}
})
if (lnwith) {
const user = await models.user.findUnique({ where: { id: lnwith.userId } })
if (user) {
return res.status(200).json({
tag: 'withdrawRequest', // type of LNURL
callback: process.env.LNWITH_URL, // The URL which LN SERVICE would accept a withdrawal Lightning invoice as query parameter
k1: query.k1, // Random or non-random string to identify the user's LN WALLET when using the callback URL
defaultDescription: `Withdrawal for @${user.name} on SN`, // A default withdrawal invoice description
minWithdrawable: user.msats >= 1000n ? 1000 : 0, // Min amount (in millisatoshis) the user can withdraw from LN SERVICE
maxWithdrawable: Math.max(Number(user.msats - 10000n), 0) // Max amount (in millisatoshis) the user can withdraw from LN SERVICE
})
} else {
reason = 'user not found'
}
} else {
reason = 'withdrawal not found'
}
} catch (error) {
console.log(error)
reason = 'internal server error'
}
console.log(reason)
return res.status(400).json({ status: 'ERROR', reason })
}
async function doWithdrawal (query, res, headers) {
const lnwith = await models.lnWith.findUnique({ where: { k1: query.k1 } })
if (!lnwith) {
return res.status(400).json({ status: 'ERROR', reason: 'invalid k1' })
}
const me = await models.user.findUnique({ where: { id: lnwith.userId } })
if (!me) {
return res.status(400).json({ status: 'ERROR', reason: 'user not found' })
}
try {
const withdrawal = await createWithdrawal(null,
{ invoice: query.pr, maxFee: me.withdrawMaxFeeDefault },
{ me, models, lnd, headers })
// store withdrawal id lnWith so client can show it
await models.lnWith.update({ where: { k1: query.k1 }, data: { withdrawalId: Number(withdrawal.id) } })
return res.status(200).json({ status: 'OK' })
} catch (e) {
console.log(e)
return res.status(400).json({ status: 'ERROR', reason: e.message || e.toString?.() || 'error creating withdrawal' })
}
}