From 13f3a895407af079a60ac890fda5485256311bb5 Mon Sep 17 00:00:00 2001 From: keyan Date: Sun, 17 Dec 2023 15:14:59 -0600 Subject: [PATCH] gofac node ip --- api/resolvers/ofac.js | 8 ++++---- api/resolvers/wallet.js | 19 +++++++++++++------ pages/api/lnwith.js | 34 +++++++++++++++------------------- 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/api/resolvers/ofac.js b/api/resolvers/ofac.js index 26b9b2a6..a418ebdd 100644 --- a/api/resolvers/ofac.js +++ b/api/resolvers/ofac.js @@ -1,8 +1,8 @@ import { GraphQLError } from 'graphql' // this function makes america more secure apparently -export default async function assertGofacYourself ({ models, headers }) { - const country = await gOFACYourself({ models, headers }) +export default async function assertGofacYourself ({ models, headers, ip }) { + const country = await gOFACYourself({ models, headers, ip }) if (!country) return throw new GraphQLError( @@ -10,9 +10,9 @@ export default async function assertGofacYourself ({ models, headers }) { { 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 ip = xRealIp || xForwardedFor?.split(',')?.[0] + ip ||= xRealIp || xForwardedFor?.split(',')?.[0] if (!ip) return false const countries = await models.$queryRaw` diff --git a/api/resolvers/wallet.js b/api/resolvers/wallet.js index ba7c5483..7362e2f6 100644 --- a/api/resolvers/wallet.js +++ b/api/resolvers/wallet.js @@ -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 crypto from 'crypto' import serialize from './serial' @@ -316,8 +316,6 @@ export default { }, createWithdrawl: createWithdrawal, sendToLnAddr: async (parent, { addr, amount, maxFee, comment, ...payer }, { me, models, lnd, headers }) => { - await assertGofacYourself({ models, headers }) - if (!me) { throw new GraphQLError('you must be logged in', { extensions: { code: 'FORBIDDEN' } }) } @@ -370,7 +368,7 @@ export default { } // 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 }) => { 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 assertGofacYourself({ models, headers }) // remove 'lightning:' prefix if present invoice = invoice.replace(/^lightning:/, '') // decode invoice to get amount - let decoded + let decoded, node try { decoded = await decodePaymentRequest({ lnd, request: invoice }) + node = await getNode({ lnd, public_key: decoded.destination, is_omitting_channels: true }) } catch (error) { console.log(error) 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) { throw new GraphQLError('your invoice must specify an amount', { extensions: { code: 'BAD_INPUT' } }) } diff --git a/pages/api/lnwith.js b/pages/api/lnwith.js index f262c7b0..1f146b70 100644 --- a/pages/api/lnwith.js +++ b/pages/api/lnwith.js @@ -1,10 +1,9 @@ // verify k1 exists // send back 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 lnd from '../../api/lnd' +import { createWithdrawal } from '../../api/resolvers/wallet' export default async ({ query, headers }, res) => { if (!query.k1) { @@ -13,8 +12,7 @@ export default async ({ query, headers }, res) => { if (query.pr) { try { - await assertGofacYourself({ models, headers }) - return doWithdrawal(query, res) + return await doWithdrawal(query, res, headers) } catch (e) { 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 }) } -async function doWithdrawal (query, res) { +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' }) @@ -67,19 +65,17 @@ async function doWithdrawal (query, res) { return res.status(400).json({ status: 'ERROR', reason: 'user not found' }) } - // create withdrawal in gql - const client = await getSSRApolloClient({ me }) - const { error, data } = await client.mutate({ - mutation: CREATE_WITHDRAWL, - variables: { invoice: query.pr, maxFee: 10 } - }) + try { + const withdrawal = await createWithdrawal(null, + { invoice: query.pr, maxFee: me.withdrawMaxFeeDefault }, + { me, models, lnd, headers }) - if (error || !data?.createWithdrawl) { - return res.status(400).json({ status: 'ERROR', reason: error?.toString() || 'could not generate withdrawl' }) + // 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' }) } - - // 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' }) }