From 0dd79eecf647964647381ab93df0a1db3ec16496 Mon Sep 17 00:00:00 2001 From: boufni95 Date: Fri, 4 Oct 2024 16:47:01 +0000 Subject: [PATCH] full access, freq+bol11 --- package-lock.json | 7 ++-- package.json | 2 +- proto/autogenerated/go/types.go | 12 ++++--- proto/autogenerated/ts/types.ts | 9 ++++++ proto/service/structs.proto | 1 + src/services/main/debitManager.ts | 53 ++++++++++++++++++++----------- 6 files changed, 57 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index 18d6503a..d959cec0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "grpc-tools": "^1.12.4", "jsonwebtoken": "^9.0.2", "lodash": "^4.17.21", - "nostr-tools": "github:shocknet/nostr-tools#ef16463592e2f7b5bf18abc86ff974615d64bb7d", + "nostr-tools": "github:shocknet/nostr-tools#19271c4bcc9ff9bf18f9208e2d9fd6870e5f350c", "pg": "^8.4.0", "reflect-metadata": "^0.2.2", "rimraf": "^3.0.2", @@ -3802,8 +3802,9 @@ }, "node_modules/nostr-tools": { "version": "2.8.0", - "resolved": "git+ssh://git@github.com/shocknet/nostr-tools.git#ef16463592e2f7b5bf18abc86ff974615d64bb7d", - "integrity": "sha512-PSBLCTv5ruThR2uS4CRIFgqU6kySxPpDWiqit2Lkc3c1RbTeyhKMr9pRnLSoulkdRZGtDYSTgmoBxvqPkqO8XQ==", + "resolved": "git+ssh://git@github.com/shocknet/nostr-tools.git#19271c4bcc9ff9bf18f9208e2d9fd6870e5f350c", + "integrity": "sha512-NWYu4yx9UELd4M333r6Eirg0lKK9vyEiUW/8DDorZtxSlBdH4B9FqH8w7VJrG2LfPJABC89EH6+VNLz7RENCfg==", + "license": "Unlicense", "dependencies": { "@noble/ciphers": "^0.5.1", "@noble/curves": "1.2.0", diff --git a/package.json b/package.json index a816c25a..36e7c437 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "grpc-tools": "^1.12.4", "jsonwebtoken": "^9.0.2", "lodash": "^4.17.21", - "nostr-tools": "github:shocknet/nostr-tools#ef16463592e2f7b5bf18abc86ff974615d64bb7d", + "nostr-tools": "github:shocknet/nostr-tools#19271c4bcc9ff9bf18f9208e2d9fd6870e5f350c", "pg": "^8.4.0", "reflect-metadata": "^0.2.2", "rimraf": "^3.0.2", diff --git a/proto/autogenerated/go/types.go b/proto/autogenerated/go/types.go index 7769ada6..1f29f6b5 100644 --- a/proto/autogenerated/go/types.go +++ b/proto/autogenerated/go/types.go @@ -531,12 +531,14 @@ type DebitRule_rule struct { type LiveDebitRequest_debit_type string const ( - FREQUENCY LiveDebitRequest_debit_type = "frequency" - INVOICE LiveDebitRequest_debit_type = "invoice" + FREQUENCY LiveDebitRequest_debit_type = "frequency" + FULL_ACCESS LiveDebitRequest_debit_type = "full_access" + INVOICE LiveDebitRequest_debit_type = "invoice" ) type LiveDebitRequest_debit struct { - Type LiveDebitRequest_debit_type `json:"type"` - Frequency *FrequencyRule `json:"frequency"` - Invoice *string `json:"invoice"` + Type LiveDebitRequest_debit_type `json:"type"` + Frequency *FrequencyRule `json:"frequency"` + Full_access *Empty `json:"full_access"` + Invoice *string `json:"invoice"` } diff --git a/proto/autogenerated/ts/types.ts b/proto/autogenerated/ts/types.ts index b3de5706..a142deca 100644 --- a/proto/autogenerated/ts/types.ts +++ b/proto/autogenerated/ts/types.ts @@ -2945,6 +2945,7 @@ export const DebitRule_ruleValidate = (o?: DebitRule_rule, opts:DebitRule_ruleOp } export enum LiveDebitRequest_debit_type { FREQUENCY = 'frequency', + FULL_ACCESS = 'full_access', INVOICE = 'invoice', } export const enumCheckLiveDebitRequest_debit_type = (e?: LiveDebitRequest_debit_type): boolean => { @@ -2953,10 +2954,12 @@ export const enumCheckLiveDebitRequest_debit_type = (e?: LiveDebitRequest_debit_ } export type LiveDebitRequest_debit = {type:LiveDebitRequest_debit_type.FREQUENCY, frequency:FrequencyRule}| + {type:LiveDebitRequest_debit_type.FULL_ACCESS, full_access:Empty}| {type:LiveDebitRequest_debit_type.INVOICE, invoice:string} export type LiveDebitRequest_debitOptions = { frequency_Options?: FrequencyRuleOptions + full_access_Options?: EmptyOptions invoice_CustomCheck?: (v: string) => boolean } export const LiveDebitRequest_debitValidate = (o?: LiveDebitRequest_debit, opts:LiveDebitRequest_debitOptions = {}, path: string = 'LiveDebitRequest_debit::root.'): Error | null => { @@ -2968,6 +2971,12 @@ export const LiveDebitRequest_debitValidate = (o?: LiveDebitRequest_debit, opts: if (frequencyErr !== null) return frequencyErr + break + case LiveDebitRequest_debit_type.FULL_ACCESS: + const full_accessErr = EmptyValidate(o.full_access, opts.full_access_Options, `${path}.full_access`) + if (full_accessErr !== null) return full_accessErr + + break case LiveDebitRequest_debit_type.INVOICE: if (typeof o.invoice !== 'string') return new Error(`${path}.invoice: is not a string`) diff --git a/proto/service/structs.proto b/proto/service/structs.proto index d3cbbbc6..1d320f9e 100644 --- a/proto/service/structs.proto +++ b/proto/service/structs.proto @@ -536,6 +536,7 @@ message LiveDebitRequest { oneof debit { string invoice = 3; FrequencyRule frequency = 4; + Empty full_access = 5; } } diff --git a/src/services/main/debitManager.ts b/src/services/main/debitManager.ts index aa387611..881039e8 100644 --- a/src/services/main/debitManager.ts +++ b/src/services/main/debitManager.ts @@ -10,10 +10,9 @@ import { Application } from '../storage/entity/Application.js'; import { ApplicationUser } from '../storage/entity/ApplicationUser.js'; import { NostrEvent, NostrSend, SendData, SendInitiator } from '../nostr/handler.js'; import { UnsignedEvent } from 'nostr-tools'; +import { BudgetFrequency, NdebitData, NdebitFailure, NdebitSuccess, NdebitSuccessPayment, RecurringDebitTimeUnit } from 'nostr-tools/lib/types/nip68.js'; export const expirationRuleName = 'expiration' export const frequencyRuleName = 'frequency' -type RecurringDebitTimeUnit = 'day' | 'week' | 'month' -type RecurringDebit = { frequency: { number: number, unit: RecurringDebitTimeUnit } } const unitToIntervalType = (unit: RecurringDebitTimeUnit) => { switch (unit) { case 'day': return Types.IntervalType.DAY @@ -93,11 +92,6 @@ const debitAccessRulesToDebitRules = (rules: DebitAccessRules | null): Types.Deb } }) } - -export type NdebitData = { pointer?: string, amount_sats: number } & (RecurringDebit | { bolt11: string }) -export type NdebitSuccess = { res: 'ok' } -export type NdebitSuccessPayment = { res: 'ok', preimage: string } -export type NdebitFailure = { res: 'GFY', error: string, code: number } const nip68errs = { 1: "Request Denied Warning", 2: "Temporary Failure", @@ -244,7 +238,7 @@ export class DebitManager { doNdebit = async (event: NostrEvent, pointerdata: NdebitData): Promise => { const { appId, pub: requestorPub } = event - const { amount_sats, pointer } = pointerdata + const { amount_sats, pointer, bolt11, frequency } = pointerdata if (!pointer) { // TODO: debit from app owner balance return { status: 'fail', debitRes: { res: 'GFY', error: nip68errs[1], code: 1 } } @@ -252,9 +246,14 @@ export class DebitManager { const appUserId = pointer const app = await this.storage.applicationStorage.GetApplication(appId) const appUser = await this.storage.applicationStorage.GetApplicationUser(app, appUserId) - const pointerFreq = pointerdata as RecurringDebit - if (pointerFreq.frequency) { - if (!amount_sats) { + let decodedAmount = null + if (bolt11) { + const decoded = await this.lnd.DecodeInvoice(bolt11) + decodedAmount = decoded.numSatoshis + } + if (frequency) { + const amt = amount_sats || decodedAmount + if (!amt) { return { status: 'fail', debitRes: { res: 'GFY', error: nip68errs[5], code: 5 } } } const debitAccess = await this.storage.debitStorage.GetDebitAccess(appUserId, requestorPub) @@ -266,9 +265,9 @@ export class DebitManager { debit: { type: Types.LiveDebitRequest_debit_type.FREQUENCY, frequency: { - interval: unitToIntervalType(pointerFreq.frequency.unit), - number_of_intervals: pointerFreq.frequency.number, - amount: pointerdata.amount_sats, + interval: unitToIntervalType(frequency.unit), + number_of_intervals: frequency.number, + amount: amt, } } } @@ -278,15 +277,33 @@ export class DebitManager { } return { status: 'authOk', debitRes: { res: 'ok' } } } - const { bolt11 } = pointerdata as { bolt11: string } + if (!bolt11) { + if (!amount_sats) { + const debitAccess = await this.storage.debitStorage.GetDebitAccess(appUserId, requestorPub) + if (!debitAccess) { + return { + status: 'authRequired', app, appUser, liveDebitReq: { + request_id: event.id, + npub: requestorPub, + debit: { + type: Types.LiveDebitRequest_debit_type.FULL_ACCESS, + full_access: {} + } + } + } + } else if (!debitAccess.authorized) { + return { status: 'fail', debitRes: { res: 'GFY', error: nip68errs[1], code: 1 } } + } + return { status: 'authOk', debitRes: { res: 'ok' } } + } return { status: 'fail', debitRes: { res: 'GFY', error: nip68errs[6], code: 6 } } } - const decoded = await this.lnd.DecodeInvoice(bolt11) - if (decoded.numSatoshis === 0) { + + if (!decodedAmount) { return { status: 'fail', debitRes: { res: 'GFY', error: nip68errs[6], code: 6 } } } - if (amount_sats && amount_sats !== decoded.numSatoshis) { + if (amount_sats && amount_sats !== decodedAmount) { return { status: 'fail', debitRes: { res: 'GFY', error: nip68errs[5], code: 5 } } }