Skip to content

Commit

Permalink
feat: add zapper support
Browse files Browse the repository at this point in the history
  • Loading branch information
im-adithya committed Nov 26, 2024
1 parent ec59c73 commit ba726b9
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 2 deletions.
4 changes: 4 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ if (!databaseUrl) {
Deno.exit(1);
}
export const DATABASE_URL = databaseUrl;

export const NOSTR_NIP57_PRIVATE_KEY = Deno.env.get("NOSTR_NIP57_PRIVATE_KEY") || "";
export const NOSTR_PUBLISHER_API_TOKEN = Deno.env.get("NOSTR_PUBLISHER_API_TOKEN") || "";
export const NOSTR_PUBLISHER_API_URL = Deno.env.get("NOSTR_PUBLISHER_API_URL") || "";
73 changes: 71 additions & 2 deletions src/nwc/nwcPool.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
import { Event, finalizeEvent } from "@nostr/tools";
import { makeZapReceipt } from "@nostr/tools/nip57";
import { nwc } from "npm:@getalby/sdk";
import { hexToBytes } from "npm:@noble/[email protected]/utils";
import { NOSTR_NIP57_PRIVATE_KEY, NOSTR_PUBLISHER_API_TOKEN, NOSTR_PUBLISHER_API_URL } from "../constants.ts";
import { decrypt } from "../db/aesgcm.ts";
import { DB } from "../db/db.ts";
import { logger } from "../logger.ts";

export class NWCPool {
private readonly _db: DB;
private readonly publisherToken: string;
private readonly publisherUrl: string;
private readonly zapperPrivateKey: string;

constructor(db: DB) {
this._db = db;
this.publisherToken = NOSTR_PUBLISHER_API_TOKEN;
this.publisherUrl = NOSTR_PUBLISHER_API_URL;
this.zapperPrivateKey = NOSTR_NIP57_PRIVATE_KEY;
}

async init() {
Expand All @@ -24,13 +35,71 @@ export class NWCPool {
});

nwcClient.subscribeNotifications(
(notification) => {
async (notification) => {
logger.debug("received notification", { userId, notification });
if (notification.notification_type === "payment_received") {
this._db.updateInvoice(userId, notification.notification)
const transaction = notification.notification
try {
this._db.updateInvoice(userId, transaction)
await this.publishZap(userId, transaction)
} catch (error) {
logger.error("error processing payment_received notification", { userId, transaction, error });
}
}
},
["payment_received"]
);
}

async publishZap(userId: number, transaction: nwc.Nip47Transaction) {
const metadata = transaction.metadata
const requestEvent = metadata?.nostr as Event

if (!requestEvent) {
return;
}

const zapReceipt = makeZapReceipt({
zapRequest: JSON.stringify(requestEvent),
preimage: transaction.preimage,
bolt11: transaction.invoice,
paidAt: new Date(transaction.settled_at * 1000)
})
const relays = requestEvent.tags.filter(tag => tag[0] === 'relays')[0].slice(1);
if (relays.length) {
logger.error("no relays specified in zap request", { user_id: userId, transaction });
return;
}

const signedEvent = finalizeEvent(zapReceipt, hexToBytes(this.zapperPrivateKey))

const response = await fetch(this.publisherUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'API-TOKEN': this.publisherToken,
},
body: JSON.stringify({
relays,
event: signedEvent,
}),
});

if (!response.ok) {
logger.error("failed to publish zap", {
user_id: userId,
event_id: signedEvent.id,
payment_hash: transaction.payment_hash,
relays,
response_status: response.status,
});
}

logger.debug("published zap", {
user_id: userId,
event_id: signedEvent.id,
payment_hash: transaction.payment_hash,
relays
});
}
}

0 comments on commit ba726b9

Please sign in to comment.