gofac node ip

This commit is contained in:
keyan 2023-12-17 15:14:59 -06:00
parent db36076541
commit 13f3a89540
3 changed files with 32 additions and 29 deletions

View File

@ -1,8 +1,8 @@
import { GraphQLError } from 'graphql' import { GraphQLError } from 'graphql'
// this function makes america more secure apparently // this function makes america more secure apparently
export default async function assertGofacYourself ({ models, headers }) { export default async function assertGofacYourself ({ models, headers, ip }) {
const country = await gOFACYourself({ models, headers }) const country = await gOFACYourself({ models, headers, ip })
if (!country) return if (!country) return
throw new GraphQLError( throw new GraphQLError(
@ -10,9 +10,9 @@ export default async function assertGofacYourself ({ models, headers }) {
{ extensions: { code: 'FORBIDDEN' } }) { extensions: { code: 'FORBIDDEN' } })
} }
export async function gOFACYourself ({ models, headers }) { export async function gOFACYourself ({ models, headers = {}, ip }) {
const { 'x-forwarded-for': xForwardedFor, 'x-real-ip': xRealIp } = headers const { 'x-forwarded-for': xForwardedFor, 'x-real-ip': xRealIp } = headers
const ip = xRealIp || xForwardedFor?.split(',')?.[0] ip ||= xRealIp || xForwardedFor?.split(',')?.[0]
if (!ip) return false if (!ip) return false
const countries = await models.$queryRaw` const countries = await models.$queryRaw`

View File

@ -1,4 +1,4 @@
import { createHodlInvoice, createInvoice, decodePaymentRequest, payViaPaymentRequest, cancelHodlInvoice, getInvoice as getInvoiceFromLnd } from 'ln-service' import { createHodlInvoice, createInvoice, decodePaymentRequest, payViaPaymentRequest, cancelHodlInvoice, getInvoice as getInvoiceFromLnd, getNode } from 'ln-service'
import { GraphQLError } from 'graphql' import { GraphQLError } from 'graphql'
import crypto from 'crypto' import crypto from 'crypto'
import serialize from './serial' import serialize from './serial'
@ -316,8 +316,6 @@ export default {
}, },
createWithdrawl: createWithdrawal, createWithdrawl: createWithdrawal,
sendToLnAddr: async (parent, { addr, amount, maxFee, comment, ...payer }, { me, models, lnd, headers }) => { sendToLnAddr: async (parent, { addr, amount, maxFee, comment, ...payer }, { me, models, lnd, headers }) => {
await assertGofacYourself({ models, headers })
if (!me) { if (!me) {
throw new GraphQLError('you must be logged in', { extensions: { code: 'FORBIDDEN' } }) throw new GraphQLError('you must be logged in', { extensions: { code: 'FORBIDDEN' } })
} }
@ -370,7 +368,7 @@ export default {
} }
// take pr and createWithdrawl // take pr and createWithdrawl
return await createWithdrawal(parent, { invoice: res.pr, maxFee }, { me, models, lnd }) return await createWithdrawal(parent, { invoice: res.pr, maxFee }, { me, models, lnd, headers })
}, },
cancelInvoice: async (parent, { hash, hmac }, { models, lnd }) => { cancelInvoice: async (parent, { hash, hmac }, { models, lnd }) => {
const hmac2 = createHmac(hash) const hmac2 = createHmac(hash)
@ -436,21 +434,30 @@ export default {
} }
} }
async function createWithdrawal (parent, { invoice, maxFee }, { me, models, lnd }) { export async function createWithdrawal (parent, { invoice, maxFee }, { me, models, lnd, headers }) {
await ssValidate(withdrawlSchema, { invoice, maxFee }) await ssValidate(withdrawlSchema, { invoice, maxFee })
await assertGofacYourself({ models, headers })
// remove 'lightning:' prefix if present // remove 'lightning:' prefix if present
invoice = invoice.replace(/^lightning:/, '') invoice = invoice.replace(/^lightning:/, '')
// decode invoice to get amount // decode invoice to get amount
let decoded let decoded, node
try { try {
decoded = await decodePaymentRequest({ lnd, request: invoice }) decoded = await decodePaymentRequest({ lnd, request: invoice })
node = await getNode({ lnd, public_key: decoded.destination, is_omitting_channels: true })
} catch (error) { } catch (error) {
console.log(error) console.log(error)
throw new GraphQLError('could not decode invoice', { extensions: { code: 'BAD_INPUT' } }) throw new GraphQLError('could not decode invoice', { extensions: { code: 'BAD_INPUT' } })
} }
if (node) {
for (const { socket } of node.sockets) {
const ip = socket.split(':')[0]
await assertGofacYourself({ models, headers, ip })
}
}
if (!decoded.mtokens || BigInt(decoded.mtokens) <= 0) { if (!decoded.mtokens || BigInt(decoded.mtokens) <= 0) {
throw new GraphQLError('your invoice must specify an amount', { extensions: { code: 'BAD_INPUT' } }) throw new GraphQLError('your invoice must specify an amount', { extensions: { code: 'BAD_INPUT' } })
} }

View File

@ -1,10 +1,9 @@
// verify k1 exists // verify k1 exists
// send back // send back
import models from '../../api/models' import models from '../../api/models'
import assertGofacYourself from '../../api/resolvers/ofac'
import getSSRApolloClient from '../../api/ssrApollo'
import { CREATE_WITHDRAWL } from '../../fragments/wallet'
import { datePivot } from '../../lib/time' import { datePivot } from '../../lib/time'
import lnd from '../../api/lnd'
import { createWithdrawal } from '../../api/resolvers/wallet'
export default async ({ query, headers }, res) => { export default async ({ query, headers }, res) => {
if (!query.k1) { if (!query.k1) {
@ -13,8 +12,7 @@ export default async ({ query, headers }, res) => {
if (query.pr) { if (query.pr) {
try { try {
await assertGofacYourself({ models, headers }) return await doWithdrawal(query, res, headers)
return doWithdrawal(query, res)
} catch (e) { } catch (e) {
return res.status(400).json({ status: 'ERROR', reason: e.message }) return res.status(400).json({ status: 'ERROR', reason: e.message })
} }
@ -57,7 +55,7 @@ export default async ({ query, headers }, res) => {
return res.status(400).json({ status: 'ERROR', reason }) return res.status(400).json({ status: 'ERROR', reason })
} }
async function doWithdrawal (query, res) { async function doWithdrawal (query, res, headers) {
const lnwith = await models.lnWith.findUnique({ where: { k1: query.k1 } }) const lnwith = await models.lnWith.findUnique({ where: { k1: query.k1 } })
if (!lnwith) { if (!lnwith) {
return res.status(400).json({ status: 'ERROR', reason: 'invalid k1' }) return res.status(400).json({ status: 'ERROR', reason: 'invalid k1' })
@ -67,19 +65,17 @@ async function doWithdrawal (query, res) {
return res.status(400).json({ status: 'ERROR', reason: 'user not found' }) return res.status(400).json({ status: 'ERROR', reason: 'user not found' })
} }
// create withdrawal in gql try {
const client = await getSSRApolloClient({ me }) const withdrawal = await createWithdrawal(null,
const { error, data } = await client.mutate({ { invoice: query.pr, maxFee: me.withdrawMaxFeeDefault },
mutation: CREATE_WITHDRAWL, { me, models, lnd, headers })
variables: { invoice: query.pr, maxFee: 10 }
})
if (error || !data?.createWithdrawl) { // store withdrawal id lnWith so client can show it
return res.status(400).json({ status: 'ERROR', reason: error?.toString() || 'could not generate withdrawl' }) 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' })
} }
// store withdrawal id lnWith so client can show it
await models.lnWith.update({ where: { k1: query.k1 }, data: { withdrawalId: Number(data.createWithdrawl.id) } })
return res.status(200).json({ status: 'OK' })
} }