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
|
||||
// ============================================================================
|
||||
|
||||
export type NotificationCategory = 'space' | 'module' | 'system' | 'social';
|
||||
export type NotificationCategory = 'space' | 'module' | 'system' | 'social' | 'payment';
|
||||
|
||||
export type NotificationEventType =
|
||||
// Space
|
||||
|
|
@ -85,7 +85,9 @@ export type NotificationEventType =
|
|||
// Delegation
|
||||
| 'delegation_received' | 'delegation_revoked' | 'delegation_expired'
|
||||
// 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 {
|
||||
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
|
||||
// ============================================================================
|
||||
|
|
|
|||
Loading…
Reference in New Issue