Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,7 @@ MDK_MNEMONIC="your_mnemonic_here"
# LND_PORT="" # ex. 8082
# LND_MACAROON="" # base64 invoices macaroon
# LND_TLS_CERT="" # base64

# Activity Logging (optional)
# Webhook URL for logging pay code registrations (e.g., Discord webhook)
# ACTIVITY_WEBHOOK_URL=""
45 changes: 45 additions & 0 deletions src/lib/notifications.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* Activity logging utilities for monitoring pay code registrations.
* Supports optional webhook notifications.
*/

type PayCodeType = "free" | "paid";

interface ActivityLogOptions {
type: PayCodeType;
domain: string;
}

/**
* Logs pay code registration activity to configured webhook (if set).
* Privacy-preserving: only logs type and domain, not usernames.
*/
export async function logPayCodeActivity(
options: ActivityLogOptions
): Promise<void> {
const webhookUrl = process.env.ACTIVITY_WEBHOOK_URL;

if (!webhookUrl) {
// Webhook not configured, skip silently
return;
}

const emoji = options.type === "free" ? "🆓" : "💰";
const label = options.type === "free" ? "Free" : "Paid";
const message = `${emoji} ${label} PayCode registered on ${options.domain}`;

try {
await fetch(webhookUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
content: message,
}),
});
} catch (error) {
// Log error but don't throw - notifications are non-critical
console.error("Failed to send activity notification:", error);
}
}
7 changes: 7 additions & 0 deletions src/server/api/routers/payCode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
createBip21FromParams,
createPayCodeParams,
} from "@/lib/util";
import { logPayCodeActivity } from "@/lib/notifications";
import axios from "axios";
import {
adjectives,
Expand Down Expand Up @@ -196,6 +197,9 @@ export const payCodeRouter = createTRPCRouter({
});
// TODO: catch and throw again?

// Log activity (non-blocking, fire-and-forget)
logPayCodeActivity({ type: "free", domain: input.domain });

return payCode;
}),

Expand Down Expand Up @@ -481,6 +485,9 @@ export const payCodeRouter = createTRPCRouter({
});
});

// Log activity (non-blocking, fire-and-forget)
logPayCodeActivity({ type: "paid", domain: payCode.domain });

return payCode;
}),

Expand Down