logs and fixies

This commit is contained in:
boufni95 2025-09-24 17:17:29 +00:00
parent c02fcc549a
commit 62e1d0c099
3 changed files with 47 additions and 34 deletions

View file

@ -10,7 +10,7 @@ import { NostrEvent, NostrSend, SendData, SendInitiator } from '../nostr/handler
import { UnsignedEvent } from 'nostr-tools'; import { UnsignedEvent } from 'nostr-tools';
import { Ndebit, NdebitData, NdebitFailure, NdebitSuccess, RecurringDebitTimeUnit } from "@shocknet/clink-sdk"; import { Ndebit, NdebitData, NdebitFailure, NdebitSuccess, RecurringDebitTimeUnit } from "@shocknet/clink-sdk";
import { debitAccessRulesToDebitRules, newNdebitResponse,debitRulesToDebitAccessRules, import { debitAccessRulesToDebitRules, newNdebitResponse,debitRulesToDebitAccessRules,
nip68errs, AuthRequiredRes, HandleNdebitRes, expirationRuleName, nofferErrors, AuthRequiredRes, HandleNdebitRes, expirationRuleName,
frequencyRuleName,IntervalTypeToSeconds,unitToIntervalType } from "./debitTypes.js"; frequencyRuleName,IntervalTypeToSeconds,unitToIntervalType } from "./debitTypes.js";
export class DebitManager { export class DebitManager {
@ -39,23 +39,6 @@ export class DebitManager {
this._nostrSend(initiator, data, relays) this._nostrSend(initiator, data, relays)
} }
/* AuthorizeDebit = async (ctx: Types.UserContext, req: Types.DebitAuthorizationRequest): Promise<Types.DebitAuthorization> => {
const access = await this.storage.debitStorage.AddDebitAccess(ctx.app_user_id, {
authorize: true,
npub: req.authorize_npub,
rules: debitRulesToDebitAccessRules(req.rules)
})
if (req.request_id) {
this.sendDebitResponse({ res: 'ok' }, { pub: req.authorize_npub, id: req.request_id, appId: ctx.app_id })
}
return {
debit_id: access.serial_id.toString(),
npub: req.authorize_npub,
authorized: true,
rules: req.rules
}
} */
GetDebitAuthorizations = async (ctx: Types.UserContext): Promise<Types.DebitAuthorizations> => { GetDebitAuthorizations = async (ctx: Types.UserContext): Promise<Types.DebitAuthorizations> => {
const allDebitsAccesses = await this.storage.debitStorage.GetAllUserDebitAccess(ctx.app_user_id) const allDebitsAccesses = await this.storage.debitStorage.GetAllUserDebitAccess(ctx.app_user_id)
const debits: Types.DebitAuthorization[] = allDebitsAccesses.map(access => ({ const debits: Types.DebitAuthorization[] = allDebitsAccesses.map(access => ({
@ -85,7 +68,8 @@ export class DebitManager {
RespondToDebit = async (ctx: Types.UserContext, req: Types.DebitResponse): Promise<void> => { RespondToDebit = async (ctx: Types.UserContext, req: Types.DebitResponse): Promise<void> => {
switch (req.response.type) { switch (req.response.type) {
case Types.DebitResponse_response_type.DENIED: case Types.DebitResponse_response_type.DENIED:
this.sendDebitResponse({ res: 'GFY', error: nip68errs[1], code: 1 }, { pub: req.npub, id: req.request_id, appId: ctx.app_id }) this.logger("🔍 [DEBIT REQUEST] Sending denied response")
this.sendDebitResponse({ res: 'GFY', error: nofferErrors[1], code: 1 }, { pub: req.npub, id: req.request_id, appId: ctx.app_id })
return return
case Types.DebitResponse_response_type.INVOICE: case Types.DebitResponse_response_type.INVOICE:
await this.paySingleInvoice(ctx, {invoice: req.response.invoice, npub: req.npub, request_id: req.request_id}) await this.paySingleInvoice(ctx, {invoice: req.response.invoice, npub: req.npub, request_id: req.request_id})
@ -100,19 +84,25 @@ export class DebitManager {
paySingleInvoice = async (ctx: Types.UserContext, {invoice,npub,request_id}:{invoice:string, npub:string, request_id:string}) => { paySingleInvoice = async (ctx: Types.UserContext, {invoice,npub,request_id}:{invoice:string, npub:string, request_id:string}) => {
try { try {
this.logger("🔍 [DEBIT REQUEST] Paying single invoice")
const app = await this.storage.applicationStorage.GetApplication(ctx.app_id) const app = await this.storage.applicationStorage.GetApplication(ctx.app_id)
const appUser = await this.storage.applicationStorage.GetApplicationUser(app, ctx.app_user_id) const appUser = await this.storage.applicationStorage.GetApplicationUser(app, ctx.app_user_id)
const { op, payment } = await this.sendDebitPayment(ctx.app_id, ctx.app_user_id, npub, invoice) const { op, payment } = await this.sendDebitPayment(ctx.app_id, ctx.app_user_id, npub, invoice)
const debitRes: NdebitSuccess = { res: 'ok', preimage: payment.preimage } const debitRes: NdebitSuccess = { res: 'ok', preimage: payment.preimage }
this.notifyPaymentSuccess(appUser, debitRes, op, { appId: ctx.app_id, pub: npub, id: request_id }) this.notifyPaymentSuccess(appUser, debitRes, op, { appId: ctx.app_id, pub: npub, id: request_id })
} catch (e: any) { } catch (e: any) {
this.sendDebitResponse({ res: 'GFY', error: nip68errs[1], code: 1 }, { pub: npub, id: request_id, appId: ctx.app_id }) this.logger("❌ [DEBIT REQUEST] Error in single invoice payment")
this.sendDebitResponse({ res: 'GFY', error: nofferErrors[1], code: 1 }, { pub: npub, id: request_id, appId: ctx.app_id })
throw e throw e
} }
} }
handleAuthorization = async(ctx: Types.UserContext,debit:Types.DebitToAuthorize, {npub,request_id}:{ npub:string, request_id:string})=>{ handleAuthorization = async (ctx: Types.UserContext,debit:Types.DebitToAuthorize, {npub,request_id}:{ npub:string, request_id:string})=>{
this.logger("🔍 [DEBIT REQUEST] Handling authorization", {
npub,
request_id,
debit
})
const access = await this.storage.debitStorage.AddDebitAccess(ctx.app_user_id, { const access = await this.storage.debitStorage.AddDebitAccess(ctx.app_user_id, {
authorize: true, authorize: true,
npub, npub,
@ -123,6 +113,7 @@ export class DebitManager {
return return
} }
if (!invoice) { if (!invoice) {
this.logger("🔍 [DEBIT REQUEST] Sending ok response")
this.sendDebitResponse({ res: 'ok' }, { pub: npub, id: request_id, appId: ctx.app_id }) this.sendDebitResponse({ res: 'ok' }, { pub: npub, id: request_id, appId: ctx.app_id })
return return
} }
@ -130,11 +121,13 @@ export class DebitManager {
const app = await this.storage.applicationStorage.GetApplication(ctx.app_id) const app = await this.storage.applicationStorage.GetApplication(ctx.app_id)
const appUser = await this.storage.applicationStorage.GetApplicationUser(app, ctx.app_user_id) const appUser = await this.storage.applicationStorage.GetApplicationUser(app, ctx.app_user_id)
this.validateAccessRules(access, app, appUser) this.validateAccessRules(access, app, appUser)
this.logger("🔍 [DEBIT REQUEST] Sending debit payment")
const { op, payment } = await this.sendDebitPayment(ctx.app_id, ctx.app_user_id, npub, invoice) const { op, payment } = await this.sendDebitPayment(ctx.app_id, ctx.app_user_id, npub, invoice)
const debitRes: NdebitSuccess = { res: 'ok', preimage: payment.preimage } const debitRes: NdebitSuccess = { res: 'ok', preimage: payment.preimage }
this.notifyPaymentSuccess(appUser, debitRes, op, { appId: ctx.app_id, pub: npub, id: request_id }) this.notifyPaymentSuccess(appUser, debitRes, op, { appId: ctx.app_id, pub: npub, id: request_id })
} catch (e: any) { } catch (e: any) {
this.sendDebitResponse({ res: 'GFY', error: nip68errs[1], code: 1 }, { pub: npub, id: request_id, appId: ctx.app_id }) this.logger("❌ [DEBIT REQUEST] Error in debit authorization")
this.sendDebitResponse({ res: 'GFY', error: nofferErrors[1], code: 1 }, { pub: npub, id: request_id, appId: ctx.app_id })
throw e throw e
} }
@ -144,7 +137,14 @@ export class DebitManager {
if (!this._nostrSend) { if (!this._nostrSend) {
throw new Error("No nostrSend attached") throw new Error("No nostrSend attached")
} }
this.logger("📥 [DEBIT REQUEST] Received debit request", {
fromPub: event.pub,
appId: event.appId,
eventId: event.id,
pointerdata
})
const res = await this.payNdebitInvoice(event, pointerdata) const res = await this.payNdebitInvoice(event, pointerdata)
this.logger("🔍 [DEBIT REQUEST] Sending ",res.status," response")
if (res.status === 'fail' || res.status === 'authOk') { if (res.status === 'fail' || res.status === 'authOk') {
const e = newNdebitResponse(JSON.stringify(res.debitRes), event) const e = newNdebitResponse(JSON.stringify(res.debitRes), event)
this.nostrSend({ type: 'app', appId: event.appId }, { type: 'event', event: e, encrypt: { toPub: event.pub } }) this.nostrSend({ type: 'app', appId: event.appId }, { type: 'event', event: e, encrypt: { toPub: event.pub } })
@ -161,7 +161,7 @@ export class DebitManager {
handleAuthRequired = (data:NdebitData, event: NostrEvent, res: AuthRequiredRes) => { handleAuthRequired = (data:NdebitData, event: NostrEvent, res: AuthRequiredRes) => {
if (!res.appUser.nostr_public_key) { if (!res.appUser.nostr_public_key) {
this.sendDebitResponse({ res: 'GFY', error: nip68errs[1], code: 1 }, { pub: event.pub, id: event.id, appId: event.appId }) this.sendDebitResponse({ res: 'GFY', error: nofferErrors[1], code: 1 }, { pub: event.pub, id: event.id, appId: event.appId })
return return
} }
const message: Types.LiveDebitRequest & { requestId: string, status: 'OK' } = { ...res.liveDebitReq, requestId: "GetLiveDebitRequests", status: 'OK' } const message: Types.LiveDebitRequest & { requestId: string, status: 'OK' } = { ...res.liveDebitReq, requestId: "GetLiveDebitRequests", status: 'OK' }
@ -185,8 +185,9 @@ export class DebitManager {
try { try {
return await this.doNdebit(event, pointerdata) return await this.doNdebit(event, pointerdata)
} catch (e: any) { } catch (e: any) {
this.logger("❌ [DEBIT ERROR] Error in debit request")
this.logger(ERROR, e.message || e) this.logger(ERROR, e.message || e)
return { status: 'fail', debitRes: { res: 'GFY', error: nip68errs[1], code: 1 } } return { status: 'fail', debitRes: { res: 'GFY', error: nofferErrors[1], code: 1 } }
} }
} }
@ -195,21 +196,24 @@ export class DebitManager {
const { amount_sats, pointer, bolt11, frequency } = pointerdata const { amount_sats, pointer, bolt11, frequency } = pointerdata
if (!pointer) { if (!pointer) {
// TODO: debit from app owner balance // TODO: debit from app owner balance
return { status: 'fail', debitRes: { res: 'GFY', error: nip68errs[1], code: 1 } } return { status: 'fail', debitRes: { res: 'GFY', error: nofferErrors[1], code: 1 } }
} }
const appUserId = pointer const appUserId = pointer
const app = await this.storage.applicationStorage.GetApplication(appId) const app = await this.storage.applicationStorage.GetApplication(appId)
const appUser = await this.storage.applicationStorage.GetApplicationUser(app, appUserId) const appUser = await this.storage.applicationStorage.GetApplicationUser(app, appUserId)
let decodedAmount = null let decodedAmount = null
if (bolt11) { if (bolt11) {
this.logger("🔍 [DEBIT REQUEST] Decoding invoice")
const decoded = await this.lnd.DecodeInvoice(bolt11) const decoded = await this.lnd.DecodeInvoice(bolt11)
decodedAmount = decoded.numSatoshis decodedAmount = decoded.numSatoshis
} }
if (frequency) { if (frequency) {
this.logger("🔍 [DEBIT REQUEST] Checking frequency")
const amt = amount_sats || decodedAmount const amt = amount_sats || decodedAmount
if (!amt) { if (!amt) {
return { status: 'fail', debitRes: { res: 'GFY', error: nip68errs[5], code: 5 } } return { status: 'fail', debitRes: { res: 'GFY', error: nofferErrors[5], code: 5 } }
} }
const debitAccess = await this.storage.debitStorage.GetDebitAccess(appUserId, requestorPub) const debitAccess = await this.storage.debitStorage.GetDebitAccess(appUserId, requestorPub)
if (!debitAccess) { if (!debitAccess) {
return { return {
@ -227,13 +231,14 @@ export class DebitManager {
} }
} }
} else if (!debitAccess.authorized) { } else if (!debitAccess.authorized) {
return { status: 'fail', debitRes: { res: 'GFY', error: nip68errs[1], code: 1 } } return { status: 'fail', debitRes: { res: 'GFY', error: nofferErrors[1], code: 1 } }
} }
return { status: 'authOk', debitRes: { res: 'ok' } } return { status: 'authOk', debitRes: { res: 'ok' } }
} }
if (!bolt11) { if (!bolt11) {
if (!amount_sats) { if (!amount_sats) {
this.logger("🔍 [DEBIT REQUEST] Checking full access")
const debitAccess = await this.storage.debitStorage.GetDebitAccess(appUserId, requestorPub) const debitAccess = await this.storage.debitStorage.GetDebitAccess(appUserId, requestorPub)
if (!debitAccess) { if (!debitAccess) {
return { return {
@ -247,20 +252,22 @@ export class DebitManager {
} }
} }
} else if (!debitAccess.authorized) { } else if (!debitAccess.authorized) {
return { status: 'fail', debitRes: { res: 'GFY', error: nip68errs[1], code: 1 } } return { status: 'fail', debitRes: { res: 'GFY', error: nofferErrors[1], code: 1 } }
} }
return { status: 'authOk', debitRes: { res: 'ok' } } return { status: 'authOk', debitRes: { res: 'ok' } }
} }
return { status: 'fail', debitRes: { res: 'GFY', error: nip68errs[6], code: 6 } } return { status: 'fail', debitRes: { res: 'GFY', error: nofferErrors[6], code: 6 } }
} }
if (!decodedAmount) { if (!decodedAmount) {
return { status: 'fail', debitRes: { res: 'GFY', error: nip68errs[6], code: 6 } } return { status: 'fail', debitRes: { res: 'GFY', error: nofferErrors[6], code: 6 } }
} }
if (amount_sats && amount_sats !== decodedAmount) { if (amount_sats && amount_sats !== decodedAmount) {
return { status: 'fail', debitRes: { res: 'GFY', error: nip68errs[5], code: 5 } } return { status: 'fail', debitRes: { res: 'GFY', error: nofferErrors[5], code: 5 } }
} }
this.logger("🔍 [DEBIT REQUEST] Checking authorization")
const authorization = await this.storage.debitStorage.GetDebitAccess(appUserId, requestorPub) const authorization = await this.storage.debitStorage.GetDebitAccess(appUserId, requestorPub)
if (!authorization) { if (!authorization) {
return { return {
@ -275,9 +282,10 @@ export class DebitManager {
} }
} }
if (!authorization.authorized) { if (!authorization.authorized) {
return { status: 'fail', debitRes: { res: 'GFY', error: nip68errs[1], code: 1 } } return { status: 'fail', debitRes: { res: 'GFY', error: nofferErrors[1], code: 1 } }
} }
await this.validateAccessRules(authorization, app, appUser) await this.validateAccessRules(authorization, app, appUser)
this.logger("🔍 [DEBIT REQUEST] Sending requested debit payment")
const { op, payment } = await this.sendDebitPayment(appId, appUserId, requestorPub, bolt11) const { op, payment } = await this.sendDebitPayment(appId, appUserId, requestorPub, bolt11)
return { status: 'invoicePaid', op, app, appUser, debitRes: { res: 'ok', preimage: payment.preimage } } return { status: 'invoicePaid', op, app, appUser, debitRes: { res: 'ok', preimage: payment.preimage } }
} }

View file

@ -86,7 +86,7 @@ export const debitAccessRulesToDebitRules = (rules: DebitAccessRules | null): Ty
} }
}) })
} }
export const nip68errs = { export const nofferErrors = {
1: "Request Denied Warning", 1: "Request Denied Warning",
2: "Temporary Failure", 2: "Temporary Failure",
3: "Expired Request", 3: "Expired Request",

View file

@ -387,6 +387,11 @@ export default (mainHandler: Main): Types.ServerMethods => {
return mainHandler.debitManager.EditDebit(ctx, req); return mainHandler.debitManager.EditDebit(ctx, req);
}, },
RespondToDebit: async ({ ctx, req }) => { RespondToDebit: async ({ ctx, req }) => {
const err = Types.DebitResponseValidate(req, {
npub_CustomCheck: pub => pub !== '',
request_id_CustomCheck: id => id !== '',
})
if (err != null) throw new Error(err.message)
return mainHandler.debitManager.RespondToDebit(ctx, req); return mainHandler.debitManager.RespondToDebit(ctx, req);
}, },
AddUserOffer: async ({ ctx, req }) => { AddUserOffer: async ({ ctx, req }) => {