feat(encryptid): add wallet lookup + payment notification APIs
CI/CD / deploy (push) Successful in 3m3s
Details
CI/CD / deploy (push) Successful in 3m3s
Details
Add internal endpoints for payment infrastructure integration: - GET /api/internal/user-by-wallet — resolve wallet to email/username - POST /api/internal/notify — trigger in-app notifications by wallet/DID - Add 'payment' notification category and payment_sent/received event types Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7e61d23799
commit
8f8ec25788
|
|
@ -67,7 +67,7 @@ async function getSmtpTransport() {
|
||||||
// TYPES
|
// TYPES
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
export type NotificationCategory = 'space' | 'module' | 'system' | 'social';
|
export type NotificationCategory = 'space' | 'module' | 'system' | 'social' | 'payment';
|
||||||
|
|
||||||
export type NotificationEventType =
|
export type NotificationEventType =
|
||||||
// Space
|
// Space
|
||||||
|
|
@ -85,7 +85,9 @@ export type NotificationEventType =
|
||||||
// Delegation
|
// Delegation
|
||||||
| 'delegation_received' | 'delegation_revoked' | 'delegation_expired'
|
| 'delegation_received' | 'delegation_revoked' | 'delegation_expired'
|
||||||
// Commitment (rTime)
|
// Commitment (rTime)
|
||||||
| 'commitment_requested' | 'commitment_accepted' | 'commitment_declined';
|
| 'commitment_requested' | 'commitment_accepted' | 'commitment_declined'
|
||||||
|
// Payment
|
||||||
|
| 'payment_sent' | 'payment_received' | 'payment_request_fulfilled';
|
||||||
|
|
||||||
export interface NotifyOptions {
|
export interface NotifyOptions {
|
||||||
userDid: string;
|
userDid: string;
|
||||||
|
|
|
||||||
|
|
@ -4260,6 +4260,66 @@ app.get('/api/internal/user-by-email', async (c) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// GET /api/internal/user-by-wallet — look up user by wallet address
|
||||||
|
app.get('/api/internal/user-by-wallet', async (c) => {
|
||||||
|
const serviceKey = c.req.header('X-Service-Key');
|
||||||
|
if (!INTERNAL_SERVICE_KEY || serviceKey !== INTERNAL_SERVICE_KEY) {
|
||||||
|
return c.json({ error: 'Unauthorized' }, 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
const wallet = c.req.query('wallet');
|
||||||
|
if (!wallet) return c.json({ found: false }, 200);
|
||||||
|
|
||||||
|
const normalizedWallet = wallet.toLowerCase().trim();
|
||||||
|
// Look up user by wallet_address field in users table
|
||||||
|
const rows = await sql`SELECT * FROM users WHERE LOWER(wallet_address) = ${normalizedWallet} LIMIT 1`;
|
||||||
|
if (rows.length === 0) return c.json({ found: false }, 200);
|
||||||
|
|
||||||
|
const profile = await getUserProfile(rows[0].id);
|
||||||
|
return c.json({
|
||||||
|
found: true,
|
||||||
|
email: profile?.profileEmail || rows[0].email || undefined,
|
||||||
|
username: profile?.username || rows[0].username || undefined,
|
||||||
|
userId: rows[0].id,
|
||||||
|
did: rows[0].did || undefined,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// POST /api/internal/notify — trigger in-app notification for a user by DID or wallet
|
||||||
|
app.post('/api/internal/notify', async (c) => {
|
||||||
|
const serviceKey = c.req.header('X-Service-Key');
|
||||||
|
if (!INTERNAL_SERVICE_KEY || serviceKey !== INTERNAL_SERVICE_KEY) {
|
||||||
|
return c.json({ error: 'Unauthorized' }, 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { userDid, wallet, category, eventType, title, body, actionUrl, actorUsername, metadata } = await c.req.json();
|
||||||
|
|
||||||
|
// Resolve DID from wallet if not provided
|
||||||
|
let resolvedDid = userDid;
|
||||||
|
if (!resolvedDid && wallet) {
|
||||||
|
const normalizedWallet = wallet.toLowerCase().trim();
|
||||||
|
const rows = await sql`SELECT did FROM users WHERE LOWER(wallet_address) = ${normalizedWallet} LIMIT 1`;
|
||||||
|
if (rows.length > 0) resolvedDid = rows[0].did;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!resolvedDid) {
|
||||||
|
return c.json({ error: 'Could not resolve user — provide userDid or a registered wallet' }, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
const notification = await notify({
|
||||||
|
userDid: resolvedDid,
|
||||||
|
category: category || 'payment',
|
||||||
|
eventType: eventType || 'payment_received',
|
||||||
|
title: title || 'Payment received',
|
||||||
|
body,
|
||||||
|
actionUrl,
|
||||||
|
actorUsername,
|
||||||
|
metadata,
|
||||||
|
});
|
||||||
|
|
||||||
|
return c.json({ success: true, notificationId: notification.id });
|
||||||
|
});
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// USER LOOKUP
|
// USER LOOKUP
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue