@happyvertical/smrt-profiles 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +53 -0
- package/CLAUDE.md +1 -0
- package/LICENSE +7 -0
- package/README.md +176 -0
- package/dist/chunks/ApiKey-B2LKEaP8.js +143 -0
- package/dist/chunks/ApiKey-B2LKEaP8.js.map +1 -0
- package/dist/chunks/ApiKeyCollection-B6Op817e.js +91 -0
- package/dist/chunks/ApiKeyCollection-B6Op817e.js.map +1 -0
- package/dist/chunks/AuditLogCollection-BYqCj0uE.js +195 -0
- package/dist/chunks/AuditLogCollection-BYqCj0uE.js.map +1 -0
- package/dist/chunks/NostrIdentityCollection-DadQBHWy.js +3065 -0
- package/dist/chunks/NostrIdentityCollection-DadQBHWy.js.map +1 -0
- package/dist/chunks/ProfileAssetCollection-D_tk1kKG.js +122 -0
- package/dist/chunks/ProfileAssetCollection-D_tk1kKG.js.map +1 -0
- package/dist/chunks/ProfileCollection-DU6wUJTO.js +782 -0
- package/dist/chunks/ProfileCollection-DU6wUJTO.js.map +1 -0
- package/dist/chunks/ProfileMetadataCollection-DEhmljMY.js +120 -0
- package/dist/chunks/ProfileMetadataCollection-DEhmljMY.js.map +1 -0
- package/dist/chunks/ProfileMetafieldCollection-DMKhSHXX.js +184 -0
- package/dist/chunks/ProfileMetafieldCollection-DMKhSHXX.js.map +1 -0
- package/dist/chunks/ProfileRelationshipCollection-C0IM8UQR.js +177 -0
- package/dist/chunks/ProfileRelationshipCollection-C0IM8UQR.js.map +1 -0
- package/dist/chunks/ProfileRelationshipTermCollection-CXem_qT-.js +117 -0
- package/dist/chunks/ProfileRelationshipTermCollection-CXem_qT-.js.map +1 -0
- package/dist/chunks/ProfileRelationshipType-BXBLldea.js +103 -0
- package/dist/chunks/ProfileRelationshipType-BXBLldea.js.map +1 -0
- package/dist/chunks/ProfileRelationshipTypeCollection-CF8YvLTV.js +48 -0
- package/dist/chunks/ProfileRelationshipTypeCollection-CF8YvLTV.js.map +1 -0
- package/dist/chunks/index-jFtOWsAV.js +1014 -0
- package/dist/chunks/index-jFtOWsAV.js.map +1 -0
- package/dist/index.d.ts +1848 -0
- package/dist/index.js +70 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.json +11829 -0
- package/dist/smrt-knowledge.json +3846 -0
- package/dist/types.d.ts +41 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +61 -0
- package/dist/utils.js +49 -0
- package/dist/utils.js.map +1 -0
- package/package.json +75 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1848 @@
|
|
|
1
|
+
import { Asset } from '@happyvertical/smrt-assets';
|
|
2
|
+
import { PromptDefinition } from '@happyvertical/smrt-prompts';
|
|
3
|
+
import { ResolvedPromptAI } from '@happyvertical/smrt-prompts';
|
|
4
|
+
import { SmrtCollection } from '@happyvertical/smrt-core';
|
|
5
|
+
import { SmrtJunction } from '@happyvertical/smrt-core';
|
|
6
|
+
import { SmrtObject } from '@happyvertical/smrt-core';
|
|
7
|
+
import { SmrtObjectOptions } from '@happyvertical/smrt-core';
|
|
8
|
+
|
|
9
|
+
export declare class ApiKey extends SmrtObject {
|
|
10
|
+
/**
|
|
11
|
+
* Link to the Profile (Person, Organization, Bot)
|
|
12
|
+
*/
|
|
13
|
+
profileId?: string;
|
|
14
|
+
/**
|
|
15
|
+
* SHA-256 hash of the API key
|
|
16
|
+
*/
|
|
17
|
+
keyHash: string;
|
|
18
|
+
/**
|
|
19
|
+
* First 8 characters of the key for identification (e.g., "sk_live_a1b2...")
|
|
20
|
+
*/
|
|
21
|
+
keyPrefix: string;
|
|
22
|
+
/**
|
|
23
|
+
* Human-readable name for the key (e.g., "CI Bot", "Local CLI")
|
|
24
|
+
*/
|
|
25
|
+
name: string;
|
|
26
|
+
/**
|
|
27
|
+
* Scopes/permissions for this key
|
|
28
|
+
*/
|
|
29
|
+
scopes: string[];
|
|
30
|
+
/**
|
|
31
|
+
* Last time this key was used
|
|
32
|
+
*/
|
|
33
|
+
lastUsedAt: Date | null;
|
|
34
|
+
/**
|
|
35
|
+
* When this key expires (null = never)
|
|
36
|
+
*/
|
|
37
|
+
expiresAt: Date | null;
|
|
38
|
+
/**
|
|
39
|
+
* When this key was revoked (null = active)
|
|
40
|
+
*/
|
|
41
|
+
revokedAt: Date | null;
|
|
42
|
+
constructor(options?: ApiKeyOptions);
|
|
43
|
+
/**
|
|
44
|
+
* Get the linked Profile
|
|
45
|
+
*/
|
|
46
|
+
getProfile(): Promise<Profile | null>;
|
|
47
|
+
/**
|
|
48
|
+
* Check if this key is valid (not expired, not revoked)
|
|
49
|
+
*/
|
|
50
|
+
isValid(): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Check if this key has a specific scope
|
|
53
|
+
*/
|
|
54
|
+
hasScope(scope: string): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Revoke this key
|
|
57
|
+
*/
|
|
58
|
+
revoke(): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Record usage of this key
|
|
61
|
+
*/
|
|
62
|
+
recordUsage(): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* Hash an API key
|
|
65
|
+
*/
|
|
66
|
+
static hashKey(key: string): string;
|
|
67
|
+
/**
|
|
68
|
+
* Generate a new API key for a profile
|
|
69
|
+
*/
|
|
70
|
+
static generate(profile: Profile, options: {
|
|
71
|
+
name: string;
|
|
72
|
+
scopes?: string[];
|
|
73
|
+
expiresAt?: Date | null;
|
|
74
|
+
db?: SmrtObjectOptions['db'];
|
|
75
|
+
}): Promise<GenerateKeyResult>;
|
|
76
|
+
/**
|
|
77
|
+
* Verify an API key and return the ApiKey record if valid
|
|
78
|
+
*/
|
|
79
|
+
static verify(key: string, options?: SmrtObjectOptions): Promise<ApiKey | null>;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export declare class ApiKeyCollection extends SmrtCollection<ApiKey> {
|
|
83
|
+
static readonly _itemClass: typeof ApiKey;
|
|
84
|
+
/**
|
|
85
|
+
* Find all keys for a profile
|
|
86
|
+
*/
|
|
87
|
+
findByProfile(profileId: string): Promise<ApiKey[]>;
|
|
88
|
+
/**
|
|
89
|
+
* Find active (non-revoked, non-expired) keys for a profile
|
|
90
|
+
*/
|
|
91
|
+
findActiveByProfile(profileId: string): Promise<ApiKey[]>;
|
|
92
|
+
/**
|
|
93
|
+
* Find key by hash
|
|
94
|
+
*/
|
|
95
|
+
findByHash(keyHash: string): Promise<ApiKey | null>;
|
|
96
|
+
/**
|
|
97
|
+
* Verify an API key string and return the record if valid
|
|
98
|
+
*/
|
|
99
|
+
verify(key: string): Promise<ApiKey | null>;
|
|
100
|
+
/**
|
|
101
|
+
* Generate a new key for a profile
|
|
102
|
+
*/
|
|
103
|
+
generateForProfile(profile: Profile, options: {
|
|
104
|
+
name: string;
|
|
105
|
+
scopes?: string[];
|
|
106
|
+
expiresAt?: Date | null;
|
|
107
|
+
}): Promise<GenerateKeyResult>;
|
|
108
|
+
/**
|
|
109
|
+
* Revoke all keys for a profile
|
|
110
|
+
*/
|
|
111
|
+
revokeAllForProfile(profileId: string): Promise<number>;
|
|
112
|
+
/**
|
|
113
|
+
* Revoke a specific key by prefix
|
|
114
|
+
*/
|
|
115
|
+
revokeByPrefix(keyPrefix: string): Promise<boolean>;
|
|
116
|
+
/**
|
|
117
|
+
* Clean up expired keys (soft delete by setting revokedAt)
|
|
118
|
+
*/
|
|
119
|
+
cleanupExpired(): Promise<number>;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export declare interface ApiKeyOptions extends SmrtObjectOptions {
|
|
123
|
+
profileId?: string;
|
|
124
|
+
name?: string;
|
|
125
|
+
scopes?: string[];
|
|
126
|
+
expiresAt?: Date | null;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export declare class AuditLog extends SmrtObject {
|
|
130
|
+
tenantId: string | null;
|
|
131
|
+
/**
|
|
132
|
+
* The profile who performed the action
|
|
133
|
+
*/
|
|
134
|
+
profileId?: string;
|
|
135
|
+
/**
|
|
136
|
+
* Action performed (e.g., 'issue.update', 'feedback.incorporate')
|
|
137
|
+
*/
|
|
138
|
+
action: string;
|
|
139
|
+
/**
|
|
140
|
+
* Type of resource affected (e.g., 'Issue', 'Repository')
|
|
141
|
+
*/
|
|
142
|
+
resourceType: string;
|
|
143
|
+
/**
|
|
144
|
+
* ID of the affected resource
|
|
145
|
+
*/
|
|
146
|
+
resourceId: string;
|
|
147
|
+
/**
|
|
148
|
+
* Source of the action
|
|
149
|
+
*/
|
|
150
|
+
source: AuditSource;
|
|
151
|
+
/**
|
|
152
|
+
* Additional context (CI run ID, request ID, etc.)
|
|
153
|
+
*/
|
|
154
|
+
metadata: Record<string, any>;
|
|
155
|
+
/**
|
|
156
|
+
* For pass-through identity in CI - the actual person who triggered
|
|
157
|
+
*/
|
|
158
|
+
onBehalfOfId?: string | null;
|
|
159
|
+
constructor(options?: AuditLogOptions);
|
|
160
|
+
/**
|
|
161
|
+
* Get the profile who performed the action
|
|
162
|
+
*/
|
|
163
|
+
getProfile(): Promise<Profile | null>;
|
|
164
|
+
/**
|
|
165
|
+
* Get the profile on whose behalf the action was performed (if any)
|
|
166
|
+
*/
|
|
167
|
+
getOnBehalfOf(): Promise<Profile | null>;
|
|
168
|
+
/**
|
|
169
|
+
* Get the effective actor (onBehalfOf if set, otherwise profile)
|
|
170
|
+
*/
|
|
171
|
+
getEffectiveActor(): Promise<Profile | null>;
|
|
172
|
+
/**
|
|
173
|
+
* Create an audit log entry
|
|
174
|
+
*/
|
|
175
|
+
static record(options: AuditLogOptions & {
|
|
176
|
+
profile: Profile;
|
|
177
|
+
onBehalfOf?: Profile | null;
|
|
178
|
+
}): Promise<AuditLog>;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export declare class AuditLogCollection extends SmrtCollection<AuditLog> {
|
|
182
|
+
static readonly _itemClass: typeof AuditLog;
|
|
183
|
+
/**
|
|
184
|
+
* Find logs for a profile (actions they performed)
|
|
185
|
+
*/
|
|
186
|
+
findByProfile(profileId: string): Promise<AuditLog[]>;
|
|
187
|
+
/**
|
|
188
|
+
* Find logs for a resource
|
|
189
|
+
*/
|
|
190
|
+
findByResource(resourceType: string, resourceId: string): Promise<AuditLog[]>;
|
|
191
|
+
/**
|
|
192
|
+
* Find logs by action type
|
|
193
|
+
*/
|
|
194
|
+
findByAction(action: string): Promise<AuditLog[]>;
|
|
195
|
+
/**
|
|
196
|
+
* Find logs by source
|
|
197
|
+
*/
|
|
198
|
+
findBySource(source: AuditSource): Promise<AuditLog[]>;
|
|
199
|
+
/**
|
|
200
|
+
* Find logs where actions were performed on behalf of someone
|
|
201
|
+
*/
|
|
202
|
+
findOnBehalfOf(profileId: string): Promise<AuditLog[]>;
|
|
203
|
+
/**
|
|
204
|
+
* Record a new audit log entry
|
|
205
|
+
*/
|
|
206
|
+
record(options: {
|
|
207
|
+
profile: Profile;
|
|
208
|
+
action: string;
|
|
209
|
+
resourceType: string;
|
|
210
|
+
resourceId: string;
|
|
211
|
+
source?: AuditSource;
|
|
212
|
+
metadata?: Record<string, any>;
|
|
213
|
+
onBehalfOf?: Profile | null;
|
|
214
|
+
}): Promise<AuditLog>;
|
|
215
|
+
/**
|
|
216
|
+
* Get recent activity for a profile
|
|
217
|
+
*/
|
|
218
|
+
getRecentActivity(profileId: string, limit?: number): Promise<AuditLog[]>;
|
|
219
|
+
/**
|
|
220
|
+
* Get activity timeline for a resource
|
|
221
|
+
*/
|
|
222
|
+
getResourceTimeline(resourceType: string, resourceId: string): Promise<AuditLog[]>;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export declare interface AuditLogOptions extends SmrtObjectOptions {
|
|
226
|
+
profileId?: string;
|
|
227
|
+
action?: string;
|
|
228
|
+
resourceType?: string;
|
|
229
|
+
resourceId?: string;
|
|
230
|
+
source?: AuditSource;
|
|
231
|
+
metadata?: Record<string, any>;
|
|
232
|
+
onBehalfOfId?: string | null;
|
|
233
|
+
tenantId?: string | null;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export declare type AuditSource = 'web' | 'cli' | 'ci' | 'webhook' | 'mcp';
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Context provided to resolveIdentity
|
|
240
|
+
*/
|
|
241
|
+
export declare interface AuthContext {
|
|
242
|
+
/**
|
|
243
|
+
* API key from X-API-Key header or similar
|
|
244
|
+
*/
|
|
245
|
+
apiKey?: string | null;
|
|
246
|
+
/**
|
|
247
|
+
* OIDC session data (from @auth/sveltekit or similar)
|
|
248
|
+
*/
|
|
249
|
+
oidcSession?: {
|
|
250
|
+
sub?: string;
|
|
251
|
+
iss?: string;
|
|
252
|
+
email?: string;
|
|
253
|
+
name?: string;
|
|
254
|
+
} | null;
|
|
255
|
+
/**
|
|
256
|
+
* Actor identifier for CI pass-through identity
|
|
257
|
+
* Usually the GitHub actor (username) who triggered the workflow
|
|
258
|
+
*/
|
|
259
|
+
actor?: string | null;
|
|
260
|
+
/**
|
|
261
|
+
* Nostr authentication data (NIP-42 style)
|
|
262
|
+
*/
|
|
263
|
+
nostrAuth?: {
|
|
264
|
+
/** Signed Nostr event for authentication */
|
|
265
|
+
event: NostrEvent;
|
|
266
|
+
/** Expected challenge (to prevent replay attacks) */
|
|
267
|
+
challenge: string;
|
|
268
|
+
} | null;
|
|
269
|
+
/**
|
|
270
|
+
* Database/persistence options
|
|
271
|
+
*/
|
|
272
|
+
db?: SmrtObjectOptions['db'];
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Bot profile type
|
|
277
|
+
*
|
|
278
|
+
* Represents automated agents, bots, and AI entities.
|
|
279
|
+
*/
|
|
280
|
+
export declare class Bot extends Profile {
|
|
281
|
+
constructor(options?: ProfileOptions);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Compute the event ID (SHA-256 hash of serialized event)
|
|
286
|
+
*/
|
|
287
|
+
export declare function computeEventId(event: NostrEvent): string;
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Create a Nostr event for authentication (NIP-42 style)
|
|
291
|
+
* @param privkey - Private key to sign with
|
|
292
|
+
* @param challenge - Server challenge string
|
|
293
|
+
* @param relay - Relay URL (optional)
|
|
294
|
+
*/
|
|
295
|
+
export declare function createAuthEvent(privkey: string, challenge: string, relay?: string): NostrEvent;
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Create a magic link service instance
|
|
299
|
+
*/
|
|
300
|
+
export declare function createMagicLinkService(config: MagicLinkConfig): MagicLinkService;
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Create a NIP-05 handler
|
|
304
|
+
*
|
|
305
|
+
* @example
|
|
306
|
+
* // SvelteKit
|
|
307
|
+
* import { createNip05Handler } from '@happyvertical/smrt-profiles';
|
|
308
|
+
*
|
|
309
|
+
* const handler = createNip05Handler({ db: { type: 'postgres', url: DATABASE_URL } });
|
|
310
|
+
*
|
|
311
|
+
* export async function GET({ url }) {
|
|
312
|
+
* const result = await handler({ name: url.searchParams.get('name') });
|
|
313
|
+
* return new Response(JSON.stringify(result.body), {
|
|
314
|
+
* status: result.status,
|
|
315
|
+
* headers: result.headers,
|
|
316
|
+
* });
|
|
317
|
+
* }
|
|
318
|
+
*
|
|
319
|
+
* @example
|
|
320
|
+
* // Express
|
|
321
|
+
* import { createNip05Handler } from '@happyvertical/smrt-profiles';
|
|
322
|
+
*
|
|
323
|
+
* const handler = createNip05Handler({ db: { type: 'postgres', url: DATABASE_URL } });
|
|
324
|
+
*
|
|
325
|
+
* app.get('/.well-known/nostr.json', async (req, res) => {
|
|
326
|
+
* const result = await handler({ name: req.query.name });
|
|
327
|
+
* res.status(result.status).set(result.headers).json(result.body);
|
|
328
|
+
* });
|
|
329
|
+
*/
|
|
330
|
+
export declare function createNip05Handler(config: Nip05HandlerConfig): (request: Nip05Request) => Promise<Nip05HandlerResult>;
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Create a profile from Nostr identity (used by magic link service)
|
|
334
|
+
*
|
|
335
|
+
* This is typically called internally by the magic link service,
|
|
336
|
+
* but can be used directly if needed.
|
|
337
|
+
*
|
|
338
|
+
* @param email - Email address for the profile
|
|
339
|
+
* @param nostrData - Encrypted Nostr keypair data
|
|
340
|
+
* @param options - Database options
|
|
341
|
+
* @returns The created profile with linked Nostr identity
|
|
342
|
+
*/
|
|
343
|
+
export declare function createProfileFromNostr(email: string, nostrData: {
|
|
344
|
+
pubkey: string;
|
|
345
|
+
encryptedPrivkey: string;
|
|
346
|
+
encryptionIv: string;
|
|
347
|
+
encryptionTag: string;
|
|
348
|
+
nip05Username?: string;
|
|
349
|
+
}, options: SmrtObjectOptions): Promise<{
|
|
350
|
+
profile: Profile;
|
|
351
|
+
nostrIdentity: NostrIdentity;
|
|
352
|
+
created: boolean;
|
|
353
|
+
}>;
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Create a profile from OIDC claims if it doesn't exist
|
|
357
|
+
*
|
|
358
|
+
* Supports email-based account linking: if a user signs in with Google
|
|
359
|
+
* and later with GitHub using the same email, they get the same profile.
|
|
360
|
+
*
|
|
361
|
+
* Resolution order:
|
|
362
|
+
* 1. If OIDC identity (iss + sub) already exists → return linked profile
|
|
363
|
+
* 2. If verified email provided, check if profile with same email exists → link new identity
|
|
364
|
+
* 3. Otherwise, create new profile + identity
|
|
365
|
+
*
|
|
366
|
+
* Security considerations:
|
|
367
|
+
* - Email-based linking only occurs when `email_verified` is true. This prevents
|
|
368
|
+
* attackers from claiming unverified emails to hijack accounts.
|
|
369
|
+
* - Linking is automatic and irreversible through this API. Multiple OIDC
|
|
370
|
+
* identities from different providers sharing the same verified email will
|
|
371
|
+
* be associated to the same Profile.
|
|
372
|
+
* - If an OIDC provider does not supply an email, or the email changes later,
|
|
373
|
+
* existing links are not automatically updated. New sign-ins without an email
|
|
374
|
+
* or with a different email may result in a new Profile being created.
|
|
375
|
+
* - This function trusts the OIDC provider to assert correct email_verified status.
|
|
376
|
+
* Only use with trusted providers.
|
|
377
|
+
*
|
|
378
|
+
* @param claims - OIDC token claims
|
|
379
|
+
* @param provider - Provider name (e.g., 'keycloak', 'google', 'github')
|
|
380
|
+
* @param options - Database options
|
|
381
|
+
* @returns The created or existing profile with linked OIDC identity
|
|
382
|
+
*/
|
|
383
|
+
export declare function createProfileFromOidc(claims: {
|
|
384
|
+
sub: string;
|
|
385
|
+
iss: string;
|
|
386
|
+
email?: string;
|
|
387
|
+
email_verified?: boolean;
|
|
388
|
+
name?: string;
|
|
389
|
+
preferred_username?: string;
|
|
390
|
+
}, provider: string, options: SmrtObjectOptions): Promise<{
|
|
391
|
+
profile: Profile;
|
|
392
|
+
oidcIdentity: OidcIdentity;
|
|
393
|
+
created: boolean;
|
|
394
|
+
}>;
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Decrypt a private key using AES-256-GCM
|
|
398
|
+
* @param encrypted - Encrypted key data
|
|
399
|
+
* @param masterSecret - Server master secret (from env)
|
|
400
|
+
*/
|
|
401
|
+
export declare function decryptPrivkey(encrypted: EncryptedKey, masterSecret: string): string;
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Derive an encryption key from the master secret using HKDF
|
|
405
|
+
* @param masterSecret - Server master secret
|
|
406
|
+
*/
|
|
407
|
+
export declare function deriveEncryptionKey(masterSecret: string): Buffer;
|
|
408
|
+
|
|
409
|
+
export declare interface EncryptedKey {
|
|
410
|
+
/** Base64-encoded ciphertext */
|
|
411
|
+
ciphertext: string;
|
|
412
|
+
/** Base64-encoded initialization vector */
|
|
413
|
+
iv: string;
|
|
414
|
+
/** Base64-encoded authentication tag */
|
|
415
|
+
tag: string;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Encrypt a private key using AES-256-GCM
|
|
420
|
+
* @param privkey - Hex-encoded private key
|
|
421
|
+
* @param masterSecret - Server master secret (from env)
|
|
422
|
+
*/
|
|
423
|
+
export declare function encryptPrivkey(privkey: string, masterSecret: string): EncryptedKey;
|
|
424
|
+
|
|
425
|
+
export declare interface GenerateKeyResult {
|
|
426
|
+
key: string;
|
|
427
|
+
apiKey: ApiKey;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Generate a new Nostr keypair (secp256k1)
|
|
432
|
+
*/
|
|
433
|
+
export declare function generateNostrKeypair(): NostrKeypair;
|
|
434
|
+
|
|
435
|
+
export declare interface GenerateTokenResult {
|
|
436
|
+
/** The plaintext token (only available at creation time) */
|
|
437
|
+
token: string;
|
|
438
|
+
/** The MagicLinkToken record */
|
|
439
|
+
magicLinkToken: MagicLinkToken;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Get public key from private key
|
|
444
|
+
*/
|
|
445
|
+
export declare function getPublicKey(privkey: string): string;
|
|
446
|
+
|
|
447
|
+
export declare interface InitiateResult {
|
|
448
|
+
success: boolean;
|
|
449
|
+
/** The Nostr identity (existing or new) */
|
|
450
|
+
nostrIdentity?: NostrIdentity;
|
|
451
|
+
/** The profile (existing or new) */
|
|
452
|
+
profile?: Profile;
|
|
453
|
+
/** True if a new profile was created */
|
|
454
|
+
created: boolean;
|
|
455
|
+
/** Error message if success is false */
|
|
456
|
+
error?: string;
|
|
457
|
+
/** Error code for programmatic handling */
|
|
458
|
+
errorCode?: 'RATE_LIMITED_EMAIL' | 'RATE_LIMITED_IP' | 'EMAIL_SEND_FAILED';
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Validate a NIP-05 identifier format
|
|
463
|
+
* @param identifier - The identifier to validate (e.g., "alice@example.com")
|
|
464
|
+
*/
|
|
465
|
+
export declare function isValidNip05Identifier(identifier: string): boolean;
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Validate a hex-encoded private key
|
|
469
|
+
*/
|
|
470
|
+
export declare function isValidPrivkey(privkey: string): boolean;
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Validate a hex-encoded public key
|
|
474
|
+
*/
|
|
475
|
+
export declare function isValidPubkey(pubkey: string): boolean;
|
|
476
|
+
|
|
477
|
+
export declare interface MagicLinkConfig {
|
|
478
|
+
/** Base URL for magic links (e.g., "https://example.com") */
|
|
479
|
+
baseUrl: string;
|
|
480
|
+
/** Path for verification endpoint (default: "/auth/verify") */
|
|
481
|
+
verifyPath?: string;
|
|
482
|
+
/** Token expiration in minutes (default: 15) */
|
|
483
|
+
expiresInMinutes?: number;
|
|
484
|
+
/** Maximum tokens per email per hour (default: 5) */
|
|
485
|
+
maxTokensPerEmailPerHour?: number;
|
|
486
|
+
/** Maximum tokens per IP per hour (default: 10) */
|
|
487
|
+
maxTokensPerIpPerHour?: number;
|
|
488
|
+
/** Server master secret for encryption */
|
|
489
|
+
masterSecret: string;
|
|
490
|
+
/** Callback to send the email */
|
|
491
|
+
sendEmail: (to: string, magicLink: string) => Promise<void>;
|
|
492
|
+
/** Database options */
|
|
493
|
+
db: SmrtObjectOptions['db'];
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
export declare interface MagicLinkService {
|
|
497
|
+
/**
|
|
498
|
+
* Initiate magic link flow - generates token and sends email
|
|
499
|
+
*/
|
|
500
|
+
initiate(email: string, options?: {
|
|
501
|
+
requestedFromIp?: string;
|
|
502
|
+
nip05Username?: string;
|
|
503
|
+
}): Promise<InitiateResult>;
|
|
504
|
+
/**
|
|
505
|
+
* Verify a magic link token and return decrypted keypair
|
|
506
|
+
*/
|
|
507
|
+
verify(token: string): Promise<VerifyResult>;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
export declare class MagicLinkToken extends SmrtObject {
|
|
511
|
+
/**
|
|
512
|
+
* Link to the NostrIdentity this token is for
|
|
513
|
+
*/
|
|
514
|
+
nostrIdentityId?: string;
|
|
515
|
+
/**
|
|
516
|
+
* SHA-256 hash of the token (never store plaintext)
|
|
517
|
+
*/
|
|
518
|
+
tokenHash: string;
|
|
519
|
+
/**
|
|
520
|
+
* Email this token was sent to
|
|
521
|
+
*/
|
|
522
|
+
email: string;
|
|
523
|
+
/**
|
|
524
|
+
* When this token expires
|
|
525
|
+
*/
|
|
526
|
+
expiresAt: Date;
|
|
527
|
+
/**
|
|
528
|
+
* When this token was used (null = unused)
|
|
529
|
+
*/
|
|
530
|
+
usedAt: Date | null;
|
|
531
|
+
/**
|
|
532
|
+
* IP address that requested the token (for rate limiting)
|
|
533
|
+
*/
|
|
534
|
+
requestedFromIp: string;
|
|
535
|
+
/**
|
|
536
|
+
* When this token was created (for rate limiting)
|
|
537
|
+
*/
|
|
538
|
+
createdAt: Date;
|
|
539
|
+
constructor(options?: MagicLinkTokenOptions);
|
|
540
|
+
/**
|
|
541
|
+
* Hash a token using SHA-256
|
|
542
|
+
*/
|
|
543
|
+
static hashToken(token: string): string;
|
|
544
|
+
/**
|
|
545
|
+
* Generate a new magic link token
|
|
546
|
+
* @param nostrIdentity - The identity this token is for
|
|
547
|
+
* @param email - The email address to send to
|
|
548
|
+
* @param options - Additional options
|
|
549
|
+
*/
|
|
550
|
+
static generate(nostrIdentity: NostrIdentity, email: string, options?: {
|
|
551
|
+
expiresInMinutes?: number;
|
|
552
|
+
requestedFromIp?: string;
|
|
553
|
+
db?: SmrtObjectOptions['db'];
|
|
554
|
+
}): Promise<GenerateTokenResult>;
|
|
555
|
+
/**
|
|
556
|
+
* Verify a token and return the MagicLinkToken if valid
|
|
557
|
+
* @param token - The plaintext token to verify
|
|
558
|
+
* @param options - Database options
|
|
559
|
+
* @returns The MagicLinkToken if valid, null otherwise
|
|
560
|
+
*/
|
|
561
|
+
static verify(token: string, options?: SmrtObjectOptions): Promise<MagicLinkToken | null>;
|
|
562
|
+
/**
|
|
563
|
+
* Check if this token is valid (not expired and not used)
|
|
564
|
+
*/
|
|
565
|
+
isValid(): boolean;
|
|
566
|
+
/**
|
|
567
|
+
* Check if this token has expired
|
|
568
|
+
*/
|
|
569
|
+
isExpired(): boolean;
|
|
570
|
+
/**
|
|
571
|
+
* Check if this token has been used
|
|
572
|
+
*/
|
|
573
|
+
isUsed(): boolean;
|
|
574
|
+
/**
|
|
575
|
+
* Mark this token as used
|
|
576
|
+
*/
|
|
577
|
+
markUsed(): Promise<void>;
|
|
578
|
+
/**
|
|
579
|
+
* Get the NostrIdentity this token is for
|
|
580
|
+
*/
|
|
581
|
+
getNostrIdentity(): Promise<NostrIdentity | null>;
|
|
582
|
+
/**
|
|
583
|
+
* Get time remaining until expiration in seconds
|
|
584
|
+
*/
|
|
585
|
+
getTimeRemainingSeconds(): number;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
export declare class MagicLinkTokenCollection extends SmrtCollection<MagicLinkToken> {
|
|
589
|
+
static readonly _itemClass: typeof MagicLinkToken;
|
|
590
|
+
/**
|
|
591
|
+
* Find token by hash
|
|
592
|
+
*/
|
|
593
|
+
findByTokenHash(tokenHash: string): Promise<MagicLinkToken | null>;
|
|
594
|
+
/**
|
|
595
|
+
* Find active (non-expired, non-used) tokens for an email
|
|
596
|
+
*/
|
|
597
|
+
findActiveForEmail(email: string): Promise<MagicLinkToken[]>;
|
|
598
|
+
/**
|
|
599
|
+
* Find tokens for a NostrIdentity
|
|
600
|
+
*/
|
|
601
|
+
findByIdentity(nostrIdentityId: string): Promise<MagicLinkToken[]>;
|
|
602
|
+
/**
|
|
603
|
+
* Count tokens created for an email within a time window (for rate limiting)
|
|
604
|
+
* @param email - Email address
|
|
605
|
+
* @param withinMinutes - Time window in minutes
|
|
606
|
+
*/
|
|
607
|
+
countRecentByEmail(email: string, withinMinutes: number): Promise<number>;
|
|
608
|
+
/**
|
|
609
|
+
* Count tokens created from an IP within a time window (for rate limiting)
|
|
610
|
+
* @param ip - IP address
|
|
611
|
+
* @param withinMinutes - Time window in minutes
|
|
612
|
+
*/
|
|
613
|
+
countRecentByIp(ip: string, withinMinutes: number): Promise<number>;
|
|
614
|
+
/**
|
|
615
|
+
* Verify a token and return it if valid
|
|
616
|
+
*/
|
|
617
|
+
verify(token: string): Promise<MagicLinkToken | null>;
|
|
618
|
+
/**
|
|
619
|
+
* Clean up expired tokens by deleting them
|
|
620
|
+
* @returns Number of tokens deleted
|
|
621
|
+
*/
|
|
622
|
+
cleanupExpired(): Promise<number>;
|
|
623
|
+
/**
|
|
624
|
+
* Revoke all tokens for a NostrIdentity (e.g., when identity is deleted)
|
|
625
|
+
*/
|
|
626
|
+
revokeForIdentity(nostrIdentityId: string): Promise<number>;
|
|
627
|
+
/**
|
|
628
|
+
* Check if rate limit is exceeded for email
|
|
629
|
+
* @param email - Email address
|
|
630
|
+
* @param maxPerHour - Maximum tokens allowed per hour (default: 5)
|
|
631
|
+
*/
|
|
632
|
+
isRateLimitedByEmail(email: string, maxPerHour?: number): Promise<boolean>;
|
|
633
|
+
/**
|
|
634
|
+
* Check if rate limit is exceeded for IP
|
|
635
|
+
* @param ip - IP address
|
|
636
|
+
* @param maxPerHour - Maximum tokens allowed per hour (default: 10)
|
|
637
|
+
*/
|
|
638
|
+
isRateLimitedByIp(ip: string, maxPerHour?: number): Promise<boolean>;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
export declare interface MagicLinkTokenOptions extends SmrtObjectOptions {
|
|
642
|
+
nostrIdentityId?: string;
|
|
643
|
+
tokenHash?: string;
|
|
644
|
+
email?: string;
|
|
645
|
+
expiresAt?: Date;
|
|
646
|
+
usedAt?: Date | null;
|
|
647
|
+
requestedFromIp?: string;
|
|
648
|
+
createdAt?: Date;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
export declare interface Nip05HandlerConfig {
|
|
652
|
+
/** Database options */
|
|
653
|
+
db: SmrtObjectOptions['db'];
|
|
654
|
+
/** Optional: Additional relays to include for all users */
|
|
655
|
+
defaultRelays?: string[];
|
|
656
|
+
/** Optional: Cache TTL in seconds (default: 300 = 5 minutes) */
|
|
657
|
+
cacheTtlSeconds?: number;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
export declare interface Nip05HandlerResult {
|
|
661
|
+
/** The NIP-05 response body */
|
|
662
|
+
body: Nip05Response;
|
|
663
|
+
/** Suggested headers for the response */
|
|
664
|
+
headers: Record<string, string>;
|
|
665
|
+
/** HTTP status code */
|
|
666
|
+
status: number;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
export declare interface Nip05Request {
|
|
670
|
+
/** The 'name' query parameter from the request */
|
|
671
|
+
name?: string | null;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
export declare interface Nip05Response {
|
|
675
|
+
names: Record<string, string>;
|
|
676
|
+
relays?: Record<string, string[]>;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
export declare interface NostrEvent {
|
|
680
|
+
id?: string;
|
|
681
|
+
pubkey: string;
|
|
682
|
+
created_at: number;
|
|
683
|
+
kind: number;
|
|
684
|
+
tags: string[][];
|
|
685
|
+
content: string;
|
|
686
|
+
sig?: string;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
export declare class NostrIdentity extends SmrtObject {
|
|
690
|
+
/**
|
|
691
|
+
* Link to the Profile (Person, Organization, Bot)
|
|
692
|
+
*/
|
|
693
|
+
profileId?: string;
|
|
694
|
+
/**
|
|
695
|
+
* Hex-encoded secp256k1 public key (64 characters)
|
|
696
|
+
*/
|
|
697
|
+
pubkey: string;
|
|
698
|
+
/**
|
|
699
|
+
* AES-256-GCM encrypted private key (base64-encoded ciphertext)
|
|
700
|
+
*/
|
|
701
|
+
encryptedPrivkey: string;
|
|
702
|
+
/**
|
|
703
|
+
* Initialization vector for AES-GCM decryption (base64)
|
|
704
|
+
*/
|
|
705
|
+
encryptionIv: string;
|
|
706
|
+
/**
|
|
707
|
+
* Authentication tag from AES-GCM (base64)
|
|
708
|
+
*/
|
|
709
|
+
encryptionTag: string;
|
|
710
|
+
/**
|
|
711
|
+
* Email address associated with this identity
|
|
712
|
+
*/
|
|
713
|
+
email: string;
|
|
714
|
+
/**
|
|
715
|
+
* Username for NIP-05 verification (e.g., "alice" for alice@domain.com)
|
|
716
|
+
*/
|
|
717
|
+
nip05Username: string;
|
|
718
|
+
/**
|
|
719
|
+
* Last time this identity was used for authentication
|
|
720
|
+
*/
|
|
721
|
+
lastUsedAt: Date | null;
|
|
722
|
+
/**
|
|
723
|
+
* When this identity was verified via magic link
|
|
724
|
+
*/
|
|
725
|
+
verifiedAt: Date | null;
|
|
726
|
+
constructor(options?: NostrIdentityOptions);
|
|
727
|
+
/**
|
|
728
|
+
* Get the linked Profile
|
|
729
|
+
*/
|
|
730
|
+
getProfile(): Promise<Profile | null>;
|
|
731
|
+
/**
|
|
732
|
+
* Find identity by public key
|
|
733
|
+
*/
|
|
734
|
+
static findByPubkey(pubkey: string, options?: SmrtObjectOptions): Promise<NostrIdentity | null>;
|
|
735
|
+
/**
|
|
736
|
+
* Find identity by email
|
|
737
|
+
*/
|
|
738
|
+
static findByEmail(email: string, options?: SmrtObjectOptions): Promise<NostrIdentity | null>;
|
|
739
|
+
/**
|
|
740
|
+
* Find identity by NIP-05 username
|
|
741
|
+
*/
|
|
742
|
+
static findByNip05(username: string, options?: SmrtObjectOptions): Promise<NostrIdentity | null>;
|
|
743
|
+
/**
|
|
744
|
+
* Decrypt the private key using the server master secret
|
|
745
|
+
* @param masterSecret - SERVER_MASTER_SECRET from environment
|
|
746
|
+
* @returns Hex-encoded private key
|
|
747
|
+
*/
|
|
748
|
+
decryptPrivkey(masterSecret: string): string;
|
|
749
|
+
/**
|
|
750
|
+
* Get the full keypair (requires master secret)
|
|
751
|
+
* @param masterSecret - SERVER_MASTER_SECRET from environment
|
|
752
|
+
*/
|
|
753
|
+
getKeypair(masterSecret: string): {
|
|
754
|
+
pubkey: string;
|
|
755
|
+
privkey: string;
|
|
756
|
+
npub: string;
|
|
757
|
+
nsec: string;
|
|
758
|
+
};
|
|
759
|
+
/**
|
|
760
|
+
* Record usage of this identity
|
|
761
|
+
*/
|
|
762
|
+
recordUsage(): Promise<void>;
|
|
763
|
+
/**
|
|
764
|
+
* Mark this identity as verified
|
|
765
|
+
*/
|
|
766
|
+
markVerified(): Promise<void>;
|
|
767
|
+
/**
|
|
768
|
+
* Check if this identity is verified
|
|
769
|
+
*/
|
|
770
|
+
isVerified(): boolean;
|
|
771
|
+
/**
|
|
772
|
+
* Get the NIP-05 identifier (username@domain)
|
|
773
|
+
* Note: Domain must be provided by the application
|
|
774
|
+
*/
|
|
775
|
+
getNip05Identifier(domain: string): string;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
export declare class NostrIdentityCollection extends SmrtCollection<NostrIdentity> {
|
|
779
|
+
static readonly _itemClass: typeof NostrIdentity;
|
|
780
|
+
/**
|
|
781
|
+
* Find identities for a profile
|
|
782
|
+
*/
|
|
783
|
+
findByProfile(profileId: string): Promise<NostrIdentity[]>;
|
|
784
|
+
/**
|
|
785
|
+
* Find identity by public key
|
|
786
|
+
*/
|
|
787
|
+
findByPubkey(pubkey: string): Promise<NostrIdentity | null>;
|
|
788
|
+
/**
|
|
789
|
+
* Find identity by email
|
|
790
|
+
*/
|
|
791
|
+
findByEmail(email: string): Promise<NostrIdentity | null>;
|
|
792
|
+
/**
|
|
793
|
+
* Find identity by NIP-05 username
|
|
794
|
+
*/
|
|
795
|
+
findByNip05(username: string): Promise<NostrIdentity | null>;
|
|
796
|
+
/**
|
|
797
|
+
* Link a new Nostr identity to a profile with a new keypair
|
|
798
|
+
* @param profile - The profile to link to
|
|
799
|
+
* @param email - Email address for this identity
|
|
800
|
+
* @param masterSecret - Server master secret for encryption
|
|
801
|
+
* @param nip05Username - Optional NIP-05 username (defaults to email local part)
|
|
802
|
+
*/
|
|
803
|
+
createForProfile(profile: Profile, email: string, masterSecret: string, nip05Username?: string): Promise<NostrIdentity>;
|
|
804
|
+
/**
|
|
805
|
+
* Link an existing Nostr identity (with encrypted keypair) to a profile
|
|
806
|
+
*/
|
|
807
|
+
linkToProfile(profile: Profile, nostrData: {
|
|
808
|
+
pubkey: string;
|
|
809
|
+
encryptedPrivkey: string;
|
|
810
|
+
encryptionIv: string;
|
|
811
|
+
encryptionTag: string;
|
|
812
|
+
email: string;
|
|
813
|
+
nip05Username?: string;
|
|
814
|
+
}): Promise<NostrIdentity>;
|
|
815
|
+
/**
|
|
816
|
+
* Unlink a Nostr identity from a profile
|
|
817
|
+
*/
|
|
818
|
+
unlinkFromProfile(profileId: string, pubkey: string): Promise<boolean>;
|
|
819
|
+
/**
|
|
820
|
+
* Get NIP-05 response data for the /.well-known/nostr.json endpoint
|
|
821
|
+
* @param username - Optional username filter, returns all if not provided
|
|
822
|
+
*/
|
|
823
|
+
getNip05Response(username?: string): Promise<Nip05Response>;
|
|
824
|
+
/**
|
|
825
|
+
* Check if a NIP-05 username is available
|
|
826
|
+
*/
|
|
827
|
+
isNip05Available(username: string): Promise<boolean>;
|
|
828
|
+
/**
|
|
829
|
+
* Update NIP-05 username for an identity
|
|
830
|
+
*/
|
|
831
|
+
updateNip05Username(identity: NostrIdentity, newUsername: string): Promise<NostrIdentity>;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
export declare interface NostrIdentityOptions extends SmrtObjectOptions {
|
|
835
|
+
profileId?: string;
|
|
836
|
+
pubkey?: string;
|
|
837
|
+
encryptedPrivkey?: string;
|
|
838
|
+
encryptionIv?: string;
|
|
839
|
+
encryptionTag?: string;
|
|
840
|
+
email?: string;
|
|
841
|
+
nip05Username?: string;
|
|
842
|
+
lastUsedAt?: Date | null;
|
|
843
|
+
verifiedAt?: Date | null;
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
/**
|
|
847
|
+
* Nostr cryptographic utilities
|
|
848
|
+
*
|
|
849
|
+
* Handles keypair generation, encryption/decryption of private keys,
|
|
850
|
+
* signature verification, and bech32 encoding for Nostr authentication.
|
|
851
|
+
*/
|
|
852
|
+
export declare interface NostrKeypair {
|
|
853
|
+
/** Hex-encoded public key (64 characters) */
|
|
854
|
+
pubkey: string;
|
|
855
|
+
/** Hex-encoded private key (64 characters) */
|
|
856
|
+
privkey: string;
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
/**
|
|
860
|
+
* Convert npub (bech32) to hex public key
|
|
861
|
+
*/
|
|
862
|
+
export declare function npubToPubkey(npub: string): string;
|
|
863
|
+
|
|
864
|
+
/**
|
|
865
|
+
* Convert nsec (bech32) to hex private key
|
|
866
|
+
*/
|
|
867
|
+
export declare function nsecToPrivkey(nsec: string): string;
|
|
868
|
+
|
|
869
|
+
export declare class OidcIdentity extends SmrtObject {
|
|
870
|
+
/**
|
|
871
|
+
* Link to the Profile (Person, Organization, Bot)
|
|
872
|
+
*/
|
|
873
|
+
profileId?: string;
|
|
874
|
+
/**
|
|
875
|
+
* Provider name (e.g., 'keycloak', 'google', 'github')
|
|
876
|
+
*/
|
|
877
|
+
provider: string;
|
|
878
|
+
/**
|
|
879
|
+
* OIDC issuer URL (e.g., https://keycloak.example.com/realms/bmp)
|
|
880
|
+
*/
|
|
881
|
+
issuer: string;
|
|
882
|
+
/**
|
|
883
|
+
* OIDC subject claim - unique identifier from the provider
|
|
884
|
+
*/
|
|
885
|
+
subject: string;
|
|
886
|
+
/**
|
|
887
|
+
* Cached email from the IdP (for display/lookup)
|
|
888
|
+
*/
|
|
889
|
+
email: string;
|
|
890
|
+
/**
|
|
891
|
+
* Last time this identity was used for authentication
|
|
892
|
+
*/
|
|
893
|
+
lastUsedAt: Date | null;
|
|
894
|
+
constructor(options?: OidcIdentityOptions);
|
|
895
|
+
/**
|
|
896
|
+
* Get the linked Profile
|
|
897
|
+
*/
|
|
898
|
+
getProfile(): Promise<Profile | null>;
|
|
899
|
+
/**
|
|
900
|
+
* Find identity by issuer and subject
|
|
901
|
+
*/
|
|
902
|
+
static findBySubject(issuer: string, subject: string, options?: SmrtObjectOptions): Promise<OidcIdentity | null>;
|
|
903
|
+
/**
|
|
904
|
+
* Find or create identity for a profile
|
|
905
|
+
*/
|
|
906
|
+
static findOrCreate(profile: Profile, oidcData: {
|
|
907
|
+
provider: string;
|
|
908
|
+
issuer: string;
|
|
909
|
+
subject: string;
|
|
910
|
+
email?: string;
|
|
911
|
+
}, options?: SmrtObjectOptions): Promise<OidcIdentity>;
|
|
912
|
+
/**
|
|
913
|
+
* Record usage of this identity
|
|
914
|
+
*/
|
|
915
|
+
recordUsage(): Promise<void>;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
export declare class OidcIdentityCollection extends SmrtCollection<OidcIdentity> {
|
|
919
|
+
static readonly _itemClass: typeof OidcIdentity;
|
|
920
|
+
/**
|
|
921
|
+
* Find identities for a profile
|
|
922
|
+
*/
|
|
923
|
+
findByProfile(profileId: string): Promise<OidcIdentity[]>;
|
|
924
|
+
/**
|
|
925
|
+
* Find identity by issuer and subject
|
|
926
|
+
*/
|
|
927
|
+
findBySubject(issuer: string, subject: string): Promise<OidcIdentity | null>;
|
|
928
|
+
/**
|
|
929
|
+
* Find identities by provider
|
|
930
|
+
*/
|
|
931
|
+
findByProvider(provider: string): Promise<OidcIdentity[]>;
|
|
932
|
+
/**
|
|
933
|
+
* Link a new OIDC identity to a profile
|
|
934
|
+
*/
|
|
935
|
+
linkToProfile(profile: Profile, oidcData: {
|
|
936
|
+
provider: string;
|
|
937
|
+
issuer: string;
|
|
938
|
+
subject: string;
|
|
939
|
+
email?: string;
|
|
940
|
+
}): Promise<OidcIdentity>;
|
|
941
|
+
/**
|
|
942
|
+
* Unlink an OIDC identity from a profile
|
|
943
|
+
*/
|
|
944
|
+
unlinkFromProfile(profileId: string, issuer: string, subject: string): Promise<boolean>;
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
export declare interface OidcIdentityOptions extends SmrtObjectOptions {
|
|
948
|
+
profileId?: string;
|
|
949
|
+
provider?: string;
|
|
950
|
+
issuer?: string;
|
|
951
|
+
subject?: string;
|
|
952
|
+
email?: string;
|
|
953
|
+
lastUsedAt?: Date | null;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
/**
|
|
957
|
+
* Organization profile type
|
|
958
|
+
*
|
|
959
|
+
* Represents companies, groups, institutions, and other organizational entities.
|
|
960
|
+
*/
|
|
961
|
+
export declare class Organization extends Profile {
|
|
962
|
+
constructor(options?: ProfileOptions);
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
/**
|
|
966
|
+
* Parse a NIP-05 identifier into its parts
|
|
967
|
+
* @param identifier - The identifier to parse (e.g., "alice@example.com")
|
|
968
|
+
*/
|
|
969
|
+
export declare function parseNip05Identifier(identifier: string): {
|
|
970
|
+
localPart: string;
|
|
971
|
+
domain: string;
|
|
972
|
+
} | null;
|
|
973
|
+
|
|
974
|
+
/**
|
|
975
|
+
* Person profile type
|
|
976
|
+
*
|
|
977
|
+
* Represents individual people/users.
|
|
978
|
+
*/
|
|
979
|
+
export declare class Person extends Profile {
|
|
980
|
+
constructor(options?: ProfileOptions);
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
/**
|
|
984
|
+
* Convert hex private key to nsec (bech32)
|
|
985
|
+
*/
|
|
986
|
+
export declare function privkeyToNsec(privkey: string): string;
|
|
987
|
+
|
|
988
|
+
export declare class Profile extends SmrtObject {
|
|
989
|
+
tenantId: string | null;
|
|
990
|
+
typeId?: string;
|
|
991
|
+
email?: string;
|
|
992
|
+
name: string;
|
|
993
|
+
description?: string;
|
|
994
|
+
metadata: any[];
|
|
995
|
+
relationshipsFrom: any[];
|
|
996
|
+
relationshipsTo: any[];
|
|
997
|
+
constructor(options?: ProfileOptions);
|
|
998
|
+
/**
|
|
999
|
+
* Get the profile type slug for this profile
|
|
1000
|
+
*
|
|
1001
|
+
* @returns The slug of the profile type
|
|
1002
|
+
*/
|
|
1003
|
+
getTypeSlug(): Promise<string>;
|
|
1004
|
+
/**
|
|
1005
|
+
* Set the profile type by slug
|
|
1006
|
+
*
|
|
1007
|
+
* @param slug - The slug of the profile type
|
|
1008
|
+
* @throws Error if profile type not found
|
|
1009
|
+
*/
|
|
1010
|
+
setTypeBySlug(slug: string): Promise<void>;
|
|
1011
|
+
/**
|
|
1012
|
+
* Add metadata to this profile
|
|
1013
|
+
*
|
|
1014
|
+
* @param metafieldSlug - The slug of the metafield
|
|
1015
|
+
* @param value - The value to set
|
|
1016
|
+
*/
|
|
1017
|
+
addMetadata(metafieldSlug: string, value: any): Promise<void>;
|
|
1018
|
+
/**
|
|
1019
|
+
* Get all metadata for this profile as key-value object
|
|
1020
|
+
*
|
|
1021
|
+
* @returns Object with metafield slugs as keys
|
|
1022
|
+
*/
|
|
1023
|
+
getMetadata(): Promise<Record<string, any>>;
|
|
1024
|
+
/**
|
|
1025
|
+
* Update multiple metadata values
|
|
1026
|
+
*
|
|
1027
|
+
* @param metadata - Object with metafield slugs as keys and values
|
|
1028
|
+
*/
|
|
1029
|
+
updateMetadata(metadata: Record<string, any>): Promise<void>;
|
|
1030
|
+
/**
|
|
1031
|
+
* Remove metadata by metafield slug
|
|
1032
|
+
*
|
|
1033
|
+
* @param metafieldSlug - The slug of the metafield to remove
|
|
1034
|
+
*/
|
|
1035
|
+
removeMetadata(metafieldSlug: string): Promise<void>;
|
|
1036
|
+
private getProfileAssetCollection;
|
|
1037
|
+
getAssets(relationship?: string): Promise<Asset[]>;
|
|
1038
|
+
addAsset(asset: Asset, relationship?: string, sortOrder?: number): Promise<void>;
|
|
1039
|
+
removeAsset(assetId: string, relationship?: string): Promise<void>;
|
|
1040
|
+
/**
|
|
1041
|
+
* Add a relationship to another profile
|
|
1042
|
+
*
|
|
1043
|
+
* @param toProfile - The target profile
|
|
1044
|
+
* @param relationshipSlug - The type of relationship
|
|
1045
|
+
* @param contextProfile - Optional context profile for tertiary relationships
|
|
1046
|
+
*/
|
|
1047
|
+
addRelationship(toProfile: Profile, relationshipSlug: string, contextProfile?: Profile): Promise<void>;
|
|
1048
|
+
/**
|
|
1049
|
+
* Get all relationships for this profile
|
|
1050
|
+
*
|
|
1051
|
+
* @param options - Filter options (typeSlug, direction)
|
|
1052
|
+
* @returns Array of ProfileRelationship instances
|
|
1053
|
+
*/
|
|
1054
|
+
getRelationships(options?: {
|
|
1055
|
+
typeSlug?: string;
|
|
1056
|
+
direction?: 'from' | 'to' | 'all';
|
|
1057
|
+
}): Promise<ProfileRelationship[]>;
|
|
1058
|
+
/**
|
|
1059
|
+
* Get related profiles
|
|
1060
|
+
*
|
|
1061
|
+
* @param relationshipSlug - Optional filter by relationship type slug
|
|
1062
|
+
* @returns Array of related Profile instances
|
|
1063
|
+
*/
|
|
1064
|
+
getRelatedProfiles(relationshipSlug?: string): Promise<Profile[]>;
|
|
1065
|
+
/**
|
|
1066
|
+
* Remove a relationship to another profile
|
|
1067
|
+
*
|
|
1068
|
+
* @param toProfile - The target profile
|
|
1069
|
+
* @param relationshipSlug - The type of relationship to remove
|
|
1070
|
+
*/
|
|
1071
|
+
removeRelationship(toProfile: Profile, relationshipSlug: string): Promise<void>;
|
|
1072
|
+
/**
|
|
1073
|
+
* AI-powered: Generate a professional bio for this profile
|
|
1074
|
+
*
|
|
1075
|
+
* Uses the `smrtProfiles.profile.generateBio` prompt registered via
|
|
1076
|
+
* `@happyvertical/smrt-prompts`, allowing tenant- or instance-level
|
|
1077
|
+
* overrides of the template, model, and parameters at runtime.
|
|
1078
|
+
*
|
|
1079
|
+
* @returns Generated bio text
|
|
1080
|
+
*/
|
|
1081
|
+
generateBio(): Promise<string>;
|
|
1082
|
+
/**
|
|
1083
|
+
* AI-powered: Check if profile matches criteria
|
|
1084
|
+
*
|
|
1085
|
+
* @param criteria - Criteria to match against
|
|
1086
|
+
* @returns True if matches criteria
|
|
1087
|
+
*/
|
|
1088
|
+
matches(criteria: string): Promise<boolean>;
|
|
1089
|
+
/**
|
|
1090
|
+
* Find profiles by metadata key-value pair
|
|
1091
|
+
*
|
|
1092
|
+
* @param metafieldSlug - The metafield slug to search
|
|
1093
|
+
* @param value - The value to match
|
|
1094
|
+
* @returns Array of matching profiles
|
|
1095
|
+
*/
|
|
1096
|
+
static findByMetadata(_metafieldSlug: string, _value: any): Promise<Profile[]>;
|
|
1097
|
+
/**
|
|
1098
|
+
* Find profiles by type slug
|
|
1099
|
+
*
|
|
1100
|
+
* @param typeSlug - The profile type slug
|
|
1101
|
+
* @returns Array of matching profiles
|
|
1102
|
+
*/
|
|
1103
|
+
static findByType(_typeSlug: string): Promise<Profile[]>;
|
|
1104
|
+
/**
|
|
1105
|
+
* Find related profiles for a given profile
|
|
1106
|
+
*
|
|
1107
|
+
* @param profileId - The profile UUID
|
|
1108
|
+
* @param relationshipSlug - Optional filter by relationship type
|
|
1109
|
+
* @returns Array of related profiles
|
|
1110
|
+
*/
|
|
1111
|
+
static findRelated(_profileId: string, _relationshipSlug?: string): Promise<Profile[]>;
|
|
1112
|
+
/**
|
|
1113
|
+
* Search profiles by email
|
|
1114
|
+
*
|
|
1115
|
+
* @param email - The email to search for
|
|
1116
|
+
* @returns Profile or null if not found
|
|
1117
|
+
*/
|
|
1118
|
+
static searchByEmail(_email: string): Promise<Profile | null>;
|
|
1119
|
+
/**
|
|
1120
|
+
* Get all API keys for this profile
|
|
1121
|
+
*
|
|
1122
|
+
* @returns Array of API keys
|
|
1123
|
+
*/
|
|
1124
|
+
getApiKeys(): Promise<any[]>;
|
|
1125
|
+
/**
|
|
1126
|
+
* Get active (non-revoked, non-expired) API keys for this profile
|
|
1127
|
+
*
|
|
1128
|
+
* @returns Array of active API keys
|
|
1129
|
+
*/
|
|
1130
|
+
getActiveApiKeys(): Promise<any[]>;
|
|
1131
|
+
/**
|
|
1132
|
+
* Generate a new API key for this profile
|
|
1133
|
+
*
|
|
1134
|
+
* @param options - Key options (name, scopes, expiration)
|
|
1135
|
+
* @returns The generated key (plaintext) and ApiKey record
|
|
1136
|
+
*/
|
|
1137
|
+
generateApiKey(options: {
|
|
1138
|
+
name: string;
|
|
1139
|
+
scopes?: string[];
|
|
1140
|
+
expiresAt?: Date | null;
|
|
1141
|
+
}): Promise<{
|
|
1142
|
+
key: string;
|
|
1143
|
+
apiKey: any;
|
|
1144
|
+
}>;
|
|
1145
|
+
/**
|
|
1146
|
+
* Get all OIDC identities linked to this profile
|
|
1147
|
+
*
|
|
1148
|
+
* @returns Array of OIDC identity records
|
|
1149
|
+
*/
|
|
1150
|
+
getOidcIdentities(): Promise<any[]>;
|
|
1151
|
+
/**
|
|
1152
|
+
* Link a new OIDC identity to this profile
|
|
1153
|
+
*
|
|
1154
|
+
* @param oidcData - OIDC provider data
|
|
1155
|
+
* @returns The linked OIDC identity record
|
|
1156
|
+
*/
|
|
1157
|
+
linkOidcIdentity(oidcData: {
|
|
1158
|
+
provider: string;
|
|
1159
|
+
issuer: string;
|
|
1160
|
+
subject: string;
|
|
1161
|
+
email?: string;
|
|
1162
|
+
}): Promise<any>;
|
|
1163
|
+
/**
|
|
1164
|
+
* Get all Nostr identities linked to this profile
|
|
1165
|
+
*
|
|
1166
|
+
* @returns Array of Nostr identity records
|
|
1167
|
+
*/
|
|
1168
|
+
getNostrIdentities(): Promise<any[]>;
|
|
1169
|
+
/**
|
|
1170
|
+
* Link a new Nostr identity to this profile
|
|
1171
|
+
*
|
|
1172
|
+
* @param nostrData - Nostr identity data (encrypted keypair)
|
|
1173
|
+
* @returns The linked Nostr identity record
|
|
1174
|
+
*/
|
|
1175
|
+
linkNostrIdentity(nostrData: {
|
|
1176
|
+
pubkey: string;
|
|
1177
|
+
encryptedPrivkey: string;
|
|
1178
|
+
encryptionIv: string;
|
|
1179
|
+
encryptionTag: string;
|
|
1180
|
+
email: string;
|
|
1181
|
+
nip05Username?: string;
|
|
1182
|
+
}): Promise<any>;
|
|
1183
|
+
/**
|
|
1184
|
+
* Get audit logs for actions performed by this profile
|
|
1185
|
+
*
|
|
1186
|
+
* @param limit - Maximum number of logs to return
|
|
1187
|
+
* @returns Array of audit log entries
|
|
1188
|
+
*/
|
|
1189
|
+
getAuditLogs(limit?: number): Promise<any[]>;
|
|
1190
|
+
/**
|
|
1191
|
+
* Record an audit log entry for an action by this profile
|
|
1192
|
+
*
|
|
1193
|
+
* @param options - Audit log options
|
|
1194
|
+
* @returns The created audit log entry
|
|
1195
|
+
*/
|
|
1196
|
+
recordAction(options: {
|
|
1197
|
+
action: string;
|
|
1198
|
+
resourceType: string;
|
|
1199
|
+
resourceId: string;
|
|
1200
|
+
source?: 'web' | 'cli' | 'ci' | 'webhook' | 'mcp';
|
|
1201
|
+
metadata?: Record<string, any>;
|
|
1202
|
+
onBehalfOf?: Profile | null;
|
|
1203
|
+
}): Promise<any>;
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
export declare class ProfileAsset extends SmrtObject {
|
|
1207
|
+
tenantId: string | null;
|
|
1208
|
+
profileId: string;
|
|
1209
|
+
assetId: string;
|
|
1210
|
+
relationship: string;
|
|
1211
|
+
sortOrder: number;
|
|
1212
|
+
constructor(options?: ProfileAssetOptions);
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
export declare class ProfileAssetCollection extends SmrtJunction<ProfileAsset> {
|
|
1216
|
+
static readonly _itemClass: typeof ProfileAsset;
|
|
1217
|
+
protected leftField: string;
|
|
1218
|
+
protected rightField: string;
|
|
1219
|
+
private profileCollectionPromise;
|
|
1220
|
+
private getProfileCollection;
|
|
1221
|
+
getAssets(profileId: string, relationship?: string): Promise<Asset[]>;
|
|
1222
|
+
addAsset(profileId: string, asset: Asset, relationship?: string, sortOrder?: number): Promise<void>;
|
|
1223
|
+
removeAsset(profileId: string, assetId: string, relationship?: string): Promise<void>;
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
export declare interface ProfileAssetOptions extends SmrtObjectOptions {
|
|
1227
|
+
profileId?: string;
|
|
1228
|
+
assetId?: string;
|
|
1229
|
+
relationship?: string;
|
|
1230
|
+
sortOrder?: number;
|
|
1231
|
+
tenantId?: string | null;
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
export declare class ProfileCollection extends SmrtCollection<Profile> {
|
|
1235
|
+
static readonly _itemClass: typeof Profile;
|
|
1236
|
+
/**
|
|
1237
|
+
* Find a profile by email address
|
|
1238
|
+
*
|
|
1239
|
+
* @param email - The email address to search for
|
|
1240
|
+
* @returns The matching profile or null
|
|
1241
|
+
*/
|
|
1242
|
+
findByEmail(email: string): Promise<Profile | null>;
|
|
1243
|
+
/**
|
|
1244
|
+
* Find profiles by type slug
|
|
1245
|
+
*
|
|
1246
|
+
* @param typeSlug - The profile type slug to filter by
|
|
1247
|
+
* @returns Array of matching profiles
|
|
1248
|
+
*/
|
|
1249
|
+
findByType(typeSlug: string): Promise<Profile[]>;
|
|
1250
|
+
/**
|
|
1251
|
+
* Batch get metadata for multiple profiles
|
|
1252
|
+
*
|
|
1253
|
+
* @param profileIds - Array of profile UUIDs
|
|
1254
|
+
* @returns Map of profile ID to metadata object
|
|
1255
|
+
*/
|
|
1256
|
+
batchGetMetadata(profileIds: string[]): Promise<Map<string, Record<string, any>>>;
|
|
1257
|
+
/**
|
|
1258
|
+
* Batch update metadata for multiple profiles
|
|
1259
|
+
*
|
|
1260
|
+
* @param updates - Array of { profileId, data } objects
|
|
1261
|
+
*/
|
|
1262
|
+
batchUpdateMetadata(updates: Array<{
|
|
1263
|
+
profileId: string;
|
|
1264
|
+
data: Record<string, any>;
|
|
1265
|
+
}>): Promise<void>;
|
|
1266
|
+
/**
|
|
1267
|
+
* Find related profiles for a given profile
|
|
1268
|
+
*
|
|
1269
|
+
* @param profileId - The profile UUID
|
|
1270
|
+
* @param relationshipSlug - Optional filter by relationship type
|
|
1271
|
+
* @returns Array of related profiles
|
|
1272
|
+
*/
|
|
1273
|
+
findRelated(profileId: string, relationshipSlug?: string): Promise<Profile[]>;
|
|
1274
|
+
getAssets(profileId: string, relationship?: string): Promise<Asset[]>;
|
|
1275
|
+
addAsset(profileId: string, asset: Asset, relationship?: string, sortOrder?: number): Promise<void>;
|
|
1276
|
+
removeAsset(profileId: string, assetId: string, relationship?: string): Promise<void>;
|
|
1277
|
+
/**
|
|
1278
|
+
* Get the relationship network for a profile up to a maximum depth
|
|
1279
|
+
*
|
|
1280
|
+
* @param profileId - The starting profile UUID
|
|
1281
|
+
* @param options - Configuration options
|
|
1282
|
+
* @returns Map of profile ID to depth level
|
|
1283
|
+
*/
|
|
1284
|
+
getRelationshipNetwork(profileId: string, options?: {
|
|
1285
|
+
maxDepth?: number;
|
|
1286
|
+
}): Promise<Map<string, number>>;
|
|
1287
|
+
/**
|
|
1288
|
+
* Find all profiles belonging to a specific tenant
|
|
1289
|
+
*
|
|
1290
|
+
* @param tenantId - The tenant UUID to filter by
|
|
1291
|
+
* @returns Array of profiles for this tenant
|
|
1292
|
+
*/
|
|
1293
|
+
findByTenant(tenantId: string): Promise<Profile[]>;
|
|
1294
|
+
/**
|
|
1295
|
+
* Find all global profiles (without a tenant)
|
|
1296
|
+
*
|
|
1297
|
+
* @returns Array of profiles with null tenantId
|
|
1298
|
+
*/
|
|
1299
|
+
findGlobal(): Promise<Profile[]>;
|
|
1300
|
+
/**
|
|
1301
|
+
* Find profiles belonging to a tenant plus all global profiles
|
|
1302
|
+
*
|
|
1303
|
+
* @param tenantId - The tenant UUID to include
|
|
1304
|
+
* @returns Array of tenant-specific and global profiles
|
|
1305
|
+
*/
|
|
1306
|
+
findWithGlobals(tenantId: string): Promise<Profile[]>;
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
export declare class ProfileMetadata extends SmrtObject {
|
|
1310
|
+
tenantId: string | null;
|
|
1311
|
+
profileId?: string;
|
|
1312
|
+
metafieldId?: string;
|
|
1313
|
+
value: string;
|
|
1314
|
+
constructor(options?: ProfileMetadataOptions);
|
|
1315
|
+
/**
|
|
1316
|
+
* Validate this metadata value against the metafield's validation schema
|
|
1317
|
+
*
|
|
1318
|
+
* @returns True if valid, throws error if invalid
|
|
1319
|
+
*/
|
|
1320
|
+
validate(): Promise<boolean>;
|
|
1321
|
+
/**
|
|
1322
|
+
* Get the metafield slug for this metadata
|
|
1323
|
+
*
|
|
1324
|
+
* @returns The slug of the metafield
|
|
1325
|
+
*/
|
|
1326
|
+
getMetafieldSlug(): Promise<string>;
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
export declare class ProfileMetadataCollection extends SmrtCollection<ProfileMetadata> {
|
|
1330
|
+
static readonly _itemClass: typeof ProfileMetadata;
|
|
1331
|
+
/**
|
|
1332
|
+
* Get all metadata for a profile
|
|
1333
|
+
*
|
|
1334
|
+
* @param profileId - The profile UUID
|
|
1335
|
+
* @returns Array of ProfileMetadata instances
|
|
1336
|
+
*/
|
|
1337
|
+
getByProfile(profileId: string): Promise<ProfileMetadata[]>;
|
|
1338
|
+
/**
|
|
1339
|
+
* Get metadata as key-value object for a profile
|
|
1340
|
+
*
|
|
1341
|
+
* @param profileId - The profile UUID
|
|
1342
|
+
* @returns Object with metafield slugs as keys
|
|
1343
|
+
*/
|
|
1344
|
+
getMetadataObject(profileId: string): Promise<Record<string, any>>;
|
|
1345
|
+
/**
|
|
1346
|
+
* Find all profiles with a specific metadata key-value pair
|
|
1347
|
+
*
|
|
1348
|
+
* @param metafieldId - The metafield UUID
|
|
1349
|
+
* @param value - The value to match
|
|
1350
|
+
* @returns Array of profile UUIDs
|
|
1351
|
+
*/
|
|
1352
|
+
findProfilesByMetadata(metafieldId: string, value: any): Promise<string[]>;
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
export declare interface ProfileMetadataOptions extends SmrtObjectOptions {
|
|
1356
|
+
profileId?: string;
|
|
1357
|
+
metafieldId?: string;
|
|
1358
|
+
value?: string;
|
|
1359
|
+
tenantId?: string | null;
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
export declare class ProfileMetafield extends SmrtObject {
|
|
1363
|
+
tenantId: string | null;
|
|
1364
|
+
name: string;
|
|
1365
|
+
description?: string;
|
|
1366
|
+
validation?: Record<string, any>;
|
|
1367
|
+
constructor(options?: ProfileMetafieldOptions);
|
|
1368
|
+
/**
|
|
1369
|
+
* Convenience method for slug-based lookup
|
|
1370
|
+
*
|
|
1371
|
+
* @param slug - The slug to search for
|
|
1372
|
+
* @returns ProfileMetafield instance or null if not found
|
|
1373
|
+
*/
|
|
1374
|
+
static getBySlug(_slug: string): Promise<ProfileMetafield | null>;
|
|
1375
|
+
/**
|
|
1376
|
+
* Register a custom validator function
|
|
1377
|
+
*
|
|
1378
|
+
* @param name - Name of the validator (used in validation.custom field)
|
|
1379
|
+
* @param validator - The validator function
|
|
1380
|
+
*/
|
|
1381
|
+
static registerValidator(name: string, validator: ValidatorFunction): void;
|
|
1382
|
+
/**
|
|
1383
|
+
* Get a registered custom validator
|
|
1384
|
+
*
|
|
1385
|
+
* @param name - Name of the validator
|
|
1386
|
+
* @returns The validator function or undefined
|
|
1387
|
+
*/
|
|
1388
|
+
static getValidator(name: string): ValidatorFunction | undefined;
|
|
1389
|
+
/**
|
|
1390
|
+
* Validate a value against this metafield's validation schema
|
|
1391
|
+
*
|
|
1392
|
+
* @param value - The value to validate
|
|
1393
|
+
* @returns True if valid, throws ValidationError if invalid
|
|
1394
|
+
*/
|
|
1395
|
+
validateValue(value: any): Promise<boolean>;
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
export declare class ProfileMetafieldCollection extends SmrtCollection<ProfileMetafield> {
|
|
1399
|
+
static readonly _itemClass: typeof ProfileMetafield;
|
|
1400
|
+
/**
|
|
1401
|
+
* Get metafield by slug
|
|
1402
|
+
*
|
|
1403
|
+
* @param slug - The slug to search for
|
|
1404
|
+
* @returns ProfileMetafield instance or null
|
|
1405
|
+
*/
|
|
1406
|
+
getBySlug(slug: string): Promise<ProfileMetafield | null>;
|
|
1407
|
+
/**
|
|
1408
|
+
* Get or create a metafield by slug
|
|
1409
|
+
*
|
|
1410
|
+
* @param slug - The slug to search for
|
|
1411
|
+
* @param defaults - Default values if creating
|
|
1412
|
+
* @returns ProfileMetafield instance
|
|
1413
|
+
*/
|
|
1414
|
+
getOrCreateBySlug(slug: string, defaults: {
|
|
1415
|
+
name: string;
|
|
1416
|
+
description?: string;
|
|
1417
|
+
validation?: ValidationSchema;
|
|
1418
|
+
}): Promise<ProfileMetafield>;
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
export declare interface ProfileMetafieldOptions extends SmrtObjectOptions {
|
|
1422
|
+
slug?: string;
|
|
1423
|
+
name?: string;
|
|
1424
|
+
description?: string;
|
|
1425
|
+
validation?: ValidationSchema;
|
|
1426
|
+
tenantId?: string | null;
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
export declare interface ProfileOptions extends SmrtObjectOptions {
|
|
1430
|
+
typeId?: string;
|
|
1431
|
+
email?: string;
|
|
1432
|
+
name?: string;
|
|
1433
|
+
description?: string;
|
|
1434
|
+
tenantId?: string | null;
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
export declare class ProfileRelationship extends SmrtObject {
|
|
1438
|
+
tenantId: string | null;
|
|
1439
|
+
fromProfileId?: string;
|
|
1440
|
+
toProfileId?: string;
|
|
1441
|
+
typeId?: string;
|
|
1442
|
+
contextProfileId?: string;
|
|
1443
|
+
terms: any[];
|
|
1444
|
+
constructor(options?: ProfileRelationshipOptions);
|
|
1445
|
+
/**
|
|
1446
|
+
* Get the relationship type slug
|
|
1447
|
+
*
|
|
1448
|
+
* @returns The slug of the relationship type
|
|
1449
|
+
*/
|
|
1450
|
+
getTypeSlug(): Promise<string>;
|
|
1451
|
+
/**
|
|
1452
|
+
* Add a term (time period) to this relationship
|
|
1453
|
+
*
|
|
1454
|
+
* @param startedAt - Start date of the term
|
|
1455
|
+
* @param endedAt - Optional end date of the term
|
|
1456
|
+
*/
|
|
1457
|
+
addTerm(startedAt: Date, endedAt?: Date): Promise<void>;
|
|
1458
|
+
/**
|
|
1459
|
+
* End the current active term
|
|
1460
|
+
*
|
|
1461
|
+
* @param endedAt - End date for the term
|
|
1462
|
+
*/
|
|
1463
|
+
endCurrentTerm(endedAt: Date): Promise<void>;
|
|
1464
|
+
/**
|
|
1465
|
+
* Get all terms for this relationship
|
|
1466
|
+
*
|
|
1467
|
+
* @returns Array of ProfileRelationshipTerm instances
|
|
1468
|
+
*/
|
|
1469
|
+
getTerms(): Promise<ProfileRelationshipTerm[]>;
|
|
1470
|
+
/**
|
|
1471
|
+
* Get the active term (no end date)
|
|
1472
|
+
*
|
|
1473
|
+
* @returns Current term or null if none active
|
|
1474
|
+
*/
|
|
1475
|
+
getActiveTerm(): Promise<ProfileRelationshipTerm | null>;
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
export declare class ProfileRelationshipCollection extends SmrtCollection<ProfileRelationship> {
|
|
1479
|
+
static readonly _itemClass: typeof ProfileRelationship;
|
|
1480
|
+
/**
|
|
1481
|
+
* Get all relationships from a profile
|
|
1482
|
+
*
|
|
1483
|
+
* @param fromProfileId - The origin profile UUID
|
|
1484
|
+
* @param typeId - Optional filter by relationship type UUID
|
|
1485
|
+
* @returns Array of ProfileRelationship instances
|
|
1486
|
+
*/
|
|
1487
|
+
getFromProfile(fromProfileId: string, typeId?: string): Promise<ProfileRelationship[]>;
|
|
1488
|
+
/**
|
|
1489
|
+
* Get all relationships to a profile
|
|
1490
|
+
*
|
|
1491
|
+
* @param toProfileId - The target profile UUID
|
|
1492
|
+
* @param typeId - Optional filter by relationship type UUID
|
|
1493
|
+
* @returns Array of ProfileRelationship instances
|
|
1494
|
+
*/
|
|
1495
|
+
getToProfile(toProfileId: string, typeId?: string): Promise<ProfileRelationship[]>;
|
|
1496
|
+
/**
|
|
1497
|
+
* Get all relationships for a profile (both directions)
|
|
1498
|
+
*
|
|
1499
|
+
* @param profileId - The profile UUID
|
|
1500
|
+
* @param typeId - Optional filter by relationship type UUID
|
|
1501
|
+
* @returns Array of ProfileRelationship instances
|
|
1502
|
+
*/
|
|
1503
|
+
getForProfile(profileId: string, typeId?: string): Promise<ProfileRelationship[]>;
|
|
1504
|
+
/**
|
|
1505
|
+
* Check if a relationship exists between two profiles
|
|
1506
|
+
*
|
|
1507
|
+
* @param fromProfileId - The origin profile UUID
|
|
1508
|
+
* @param toProfileId - The target profile UUID
|
|
1509
|
+
* @param typeId - The relationship type UUID
|
|
1510
|
+
* @returns True if relationship exists
|
|
1511
|
+
*/
|
|
1512
|
+
exists(fromProfileId: string, toProfileId: string, typeId: string): Promise<boolean>;
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1515
|
+
export declare interface ProfileRelationshipOptions extends SmrtObjectOptions {
|
|
1516
|
+
fromProfileId?: string;
|
|
1517
|
+
toProfileId?: string;
|
|
1518
|
+
typeId?: string;
|
|
1519
|
+
contextProfileId?: string;
|
|
1520
|
+
tenantId?: string | null;
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1523
|
+
export declare class ProfileRelationshipTerm extends SmrtObject {
|
|
1524
|
+
relationshipId?: string;
|
|
1525
|
+
startedAt: Date;
|
|
1526
|
+
endedAt?: Date;
|
|
1527
|
+
constructor(options?: ProfileRelationshipTermOptions);
|
|
1528
|
+
/**
|
|
1529
|
+
* Check if this term is currently active
|
|
1530
|
+
*
|
|
1531
|
+
* @returns True if active (no end date or end date in future)
|
|
1532
|
+
*/
|
|
1533
|
+
isActive(): boolean;
|
|
1534
|
+
/**
|
|
1535
|
+
* End this term
|
|
1536
|
+
*
|
|
1537
|
+
* @param endedAt - End date for the term (defaults to now)
|
|
1538
|
+
*/
|
|
1539
|
+
end(endedAt?: Date): Promise<void>;
|
|
1540
|
+
/**
|
|
1541
|
+
* Get the duration of this term in days
|
|
1542
|
+
*
|
|
1543
|
+
* @returns Duration in days
|
|
1544
|
+
*/
|
|
1545
|
+
getDurationDays(): number;
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1548
|
+
export declare class ProfileRelationshipTermCollection extends SmrtCollection<ProfileRelationshipTerm> {
|
|
1549
|
+
static readonly _itemClass: typeof ProfileRelationshipTerm;
|
|
1550
|
+
/**
|
|
1551
|
+
* Get all terms for a relationship
|
|
1552
|
+
*
|
|
1553
|
+
* @param relationshipId - The relationship UUID
|
|
1554
|
+
* @returns Array of ProfileRelationshipTerm instances
|
|
1555
|
+
*/
|
|
1556
|
+
getByRelationship(relationshipId: string): Promise<ProfileRelationshipTerm[]>;
|
|
1557
|
+
/**
|
|
1558
|
+
* Get the active term for a relationship (no end date or future end date)
|
|
1559
|
+
*
|
|
1560
|
+
* @param relationshipId - The relationship UUID
|
|
1561
|
+
* @returns Active term or null
|
|
1562
|
+
*/
|
|
1563
|
+
getActiveTerm(relationshipId: string): Promise<ProfileRelationshipTerm | null>;
|
|
1564
|
+
/**
|
|
1565
|
+
* Get all historical (ended) terms for a relationship
|
|
1566
|
+
*
|
|
1567
|
+
* @param relationshipId - The relationship UUID
|
|
1568
|
+
* @returns Array of ended ProfileRelationshipTerm instances
|
|
1569
|
+
*/
|
|
1570
|
+
getHistoricalTerms(relationshipId: string): Promise<ProfileRelationshipTerm[]>;
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
export declare interface ProfileRelationshipTermOptions extends SmrtObjectOptions {
|
|
1574
|
+
relationshipId?: string;
|
|
1575
|
+
startedAt?: Date;
|
|
1576
|
+
endedAt?: Date;
|
|
1577
|
+
}
|
|
1578
|
+
|
|
1579
|
+
export declare class ProfileRelationshipType extends SmrtObject {
|
|
1580
|
+
name: string;
|
|
1581
|
+
reciprocal: boolean;
|
|
1582
|
+
constructor(options?: ProfileRelationshipTypeOptions);
|
|
1583
|
+
/**
|
|
1584
|
+
* Convenience method for slug-based lookup
|
|
1585
|
+
*
|
|
1586
|
+
* @param slug - The slug to search for
|
|
1587
|
+
* @returns ProfileRelationshipType instance or null if not found
|
|
1588
|
+
*/
|
|
1589
|
+
static getBySlug(_slug: string): Promise<ProfileRelationshipType | null>;
|
|
1590
|
+
/**
|
|
1591
|
+
* Register a custom reciprocal handler for a relationship type
|
|
1592
|
+
*
|
|
1593
|
+
* @param slug - The relationship type slug
|
|
1594
|
+
* @param handler - The handler function to execute when creating reciprocal relationship
|
|
1595
|
+
*/
|
|
1596
|
+
static registerReciprocalHandler(slug: string, handler: ReciprocalHandler): void;
|
|
1597
|
+
/**
|
|
1598
|
+
* Get the reciprocal handler for a relationship type
|
|
1599
|
+
*
|
|
1600
|
+
* @param slug - The relationship type slug
|
|
1601
|
+
* @returns The handler function or undefined
|
|
1602
|
+
*/
|
|
1603
|
+
static getReciprocalHandler(slug: string): ReciprocalHandler | undefined;
|
|
1604
|
+
/**
|
|
1605
|
+
* Check if a relationship type is reciprocal
|
|
1606
|
+
*
|
|
1607
|
+
* @param slug - The relationship type slug
|
|
1608
|
+
* @returns True if reciprocal, false otherwise
|
|
1609
|
+
*/
|
|
1610
|
+
static isReciprocal(slug: string): Promise<boolean>;
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
export declare class ProfileRelationshipTypeCollection extends SmrtCollection<ProfileRelationshipType> {
|
|
1614
|
+
static readonly _itemClass: typeof ProfileRelationshipType;
|
|
1615
|
+
/**
|
|
1616
|
+
* Get relationship type by slug
|
|
1617
|
+
*
|
|
1618
|
+
* @param slug - The slug to search for
|
|
1619
|
+
* @returns ProfileRelationshipType instance or null
|
|
1620
|
+
*/
|
|
1621
|
+
getBySlug(slug: string): Promise<ProfileRelationshipType | null>;
|
|
1622
|
+
/**
|
|
1623
|
+
* Get or create a relationship type by slug
|
|
1624
|
+
*
|
|
1625
|
+
* @param slug - The slug to search for
|
|
1626
|
+
* @param defaults - Default values if creating
|
|
1627
|
+
* @returns ProfileRelationshipType instance
|
|
1628
|
+
*/
|
|
1629
|
+
getOrCreateBySlug(slug: string, defaults: {
|
|
1630
|
+
name: string;
|
|
1631
|
+
reciprocal?: boolean;
|
|
1632
|
+
}): Promise<ProfileRelationshipType>;
|
|
1633
|
+
/**
|
|
1634
|
+
* Get all reciprocal relationship types
|
|
1635
|
+
*
|
|
1636
|
+
* @returns Array of reciprocal ProfileRelationshipType instances
|
|
1637
|
+
*/
|
|
1638
|
+
getReciprocal(): Promise<ProfileRelationshipType[]>;
|
|
1639
|
+
/**
|
|
1640
|
+
* Get all directional (non-reciprocal) relationship types
|
|
1641
|
+
*
|
|
1642
|
+
* @returns Array of directional ProfileRelationshipType instances
|
|
1643
|
+
*/
|
|
1644
|
+
getDirectional(): Promise<ProfileRelationshipType[]>;
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
export declare interface ProfileRelationshipTypeOptions extends SmrtObjectOptions {
|
|
1648
|
+
slug?: string;
|
|
1649
|
+
name?: string;
|
|
1650
|
+
reciprocal?: boolean;
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
export declare class ProfileType extends SmrtObject {
|
|
1654
|
+
tenantId: string | null;
|
|
1655
|
+
name: string;
|
|
1656
|
+
description?: string;
|
|
1657
|
+
constructor(options?: ProfileTypeOptions);
|
|
1658
|
+
/**
|
|
1659
|
+
* Convenience method for slug-based lookup
|
|
1660
|
+
*
|
|
1661
|
+
* @param slug - The slug to search for
|
|
1662
|
+
* @returns ProfileType instance or null if not found
|
|
1663
|
+
*/
|
|
1664
|
+
static getBySlug(_slug: string): Promise<ProfileType | null>;
|
|
1665
|
+
}
|
|
1666
|
+
|
|
1667
|
+
export declare class ProfileTypeCollection extends SmrtCollection<ProfileType> {
|
|
1668
|
+
static readonly _itemClass: typeof ProfileType;
|
|
1669
|
+
/**
|
|
1670
|
+
* Get profile type by slug
|
|
1671
|
+
*
|
|
1672
|
+
* @param slug - The slug to search for
|
|
1673
|
+
* @returns ProfileType instance or null
|
|
1674
|
+
*/
|
|
1675
|
+
getBySlug(slug: string): Promise<ProfileType | null>;
|
|
1676
|
+
/**
|
|
1677
|
+
* Get or create a profile type by slug
|
|
1678
|
+
*
|
|
1679
|
+
* @param slug - The slug to search for
|
|
1680
|
+
* @param defaults - Default values if creating
|
|
1681
|
+
* @returns ProfileType instance
|
|
1682
|
+
*/
|
|
1683
|
+
getOrCreateBySlug(slug: string, defaults: {
|
|
1684
|
+
name: string;
|
|
1685
|
+
description?: string;
|
|
1686
|
+
}): Promise<ProfileType>;
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1689
|
+
export declare interface ProfileTypeOptions extends SmrtObjectOptions {
|
|
1690
|
+
slug?: string;
|
|
1691
|
+
name?: string;
|
|
1692
|
+
description?: string;
|
|
1693
|
+
tenantId?: string | null;
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
export declare function promptMessageOptions(ai: ResolvedPromptAI): {
|
|
1697
|
+
maxTokens?: number | undefined;
|
|
1698
|
+
temperature?: number | undefined;
|
|
1699
|
+
model?: string | undefined;
|
|
1700
|
+
};
|
|
1701
|
+
|
|
1702
|
+
/**
|
|
1703
|
+
* Convert hex public key to npub (bech32)
|
|
1704
|
+
*/
|
|
1705
|
+
export declare function pubkeyToNpub(pubkey: string): string;
|
|
1706
|
+
|
|
1707
|
+
/**
|
|
1708
|
+
* TypeScript type definitions for @have/profiles package
|
|
1709
|
+
*/
|
|
1710
|
+
/**
|
|
1711
|
+
* Handler function interface for reciprocal relationships
|
|
1712
|
+
*
|
|
1713
|
+
* @param from - The profile initiating the relationship
|
|
1714
|
+
* @param to - The target profile
|
|
1715
|
+
* @param context - Optional context profile for tertiary relationships
|
|
1716
|
+
* @param options - Additional options for the handler
|
|
1717
|
+
*/
|
|
1718
|
+
export declare type ReciprocalHandler = (from: any, to: any, context?: any, options?: any) => Promise<void>;
|
|
1719
|
+
|
|
1720
|
+
/**
|
|
1721
|
+
* Resolve authentication context to a Profile
|
|
1722
|
+
*
|
|
1723
|
+
* @param context - The authentication context from the request
|
|
1724
|
+
* @returns The resolved profile and metadata
|
|
1725
|
+
*
|
|
1726
|
+
* @example
|
|
1727
|
+
* ```typescript
|
|
1728
|
+
* // In SvelteKit hooks.server.ts
|
|
1729
|
+
* import { resolveIdentity } from '@happyvertical/smrt-profiles';
|
|
1730
|
+
*
|
|
1731
|
+
* const identityMiddleware: Handle = async ({ event, resolve }) => {
|
|
1732
|
+
* const session = await event.locals.auth();
|
|
1733
|
+
*
|
|
1734
|
+
* const { profile, source } = await resolveIdentity({
|
|
1735
|
+
* oidcSession: session,
|
|
1736
|
+
* apiKey: event.request.headers.get('X-API-Key'),
|
|
1737
|
+
* actor: event.request.headers.get('X-Actor'),
|
|
1738
|
+
* db: { type: 'postgres', url: DATABASE_URL },
|
|
1739
|
+
* });
|
|
1740
|
+
*
|
|
1741
|
+
* event.locals.profile = profile;
|
|
1742
|
+
* event.locals.authSource = source;
|
|
1743
|
+
*
|
|
1744
|
+
* return resolve(event);
|
|
1745
|
+
* };
|
|
1746
|
+
* ```
|
|
1747
|
+
*/
|
|
1748
|
+
export declare function resolveIdentity(context: AuthContext): Promise<ResolveIdentityResult>;
|
|
1749
|
+
|
|
1750
|
+
/**
|
|
1751
|
+
* Result of identity resolution
|
|
1752
|
+
*/
|
|
1753
|
+
export declare interface ResolveIdentityResult {
|
|
1754
|
+
/**
|
|
1755
|
+
* The resolved profile, or null if not authenticated
|
|
1756
|
+
*/
|
|
1757
|
+
profile: Profile | null;
|
|
1758
|
+
/**
|
|
1759
|
+
* How the identity was resolved
|
|
1760
|
+
*/
|
|
1761
|
+
source: 'api_key' | 'oidc' | 'nostr' | 'actor' | 'none';
|
|
1762
|
+
/**
|
|
1763
|
+
* The API key record if authenticated via API key
|
|
1764
|
+
*/
|
|
1765
|
+
apiKey?: ApiKey;
|
|
1766
|
+
/**
|
|
1767
|
+
* The OIDC identity record if authenticated via OIDC
|
|
1768
|
+
*/
|
|
1769
|
+
oidcIdentity?: OidcIdentity;
|
|
1770
|
+
/**
|
|
1771
|
+
* The Nostr identity record if authenticated via Nostr
|
|
1772
|
+
*/
|
|
1773
|
+
nostrIdentity?: NostrIdentity;
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
/**
|
|
1777
|
+
* Sign a Nostr event using Schnorr signatures (BIP-340)
|
|
1778
|
+
* @param event - Event to sign (without id and sig)
|
|
1779
|
+
* @param privkey - Hex-encoded private key
|
|
1780
|
+
*/
|
|
1781
|
+
export declare function signEvent(event: Omit<NostrEvent, 'id' | 'sig'>, privkey: string): NostrEvent;
|
|
1782
|
+
|
|
1783
|
+
export declare const smrtProfilesGenerateBioPrompt: PromptDefinition;
|
|
1784
|
+
|
|
1785
|
+
/**
|
|
1786
|
+
* Validation schema structure for profile metadata fields
|
|
1787
|
+
*/
|
|
1788
|
+
export declare interface ValidationSchema {
|
|
1789
|
+
/** Type constraint */
|
|
1790
|
+
type?: 'string' | 'number' | 'boolean' | 'date' | 'json';
|
|
1791
|
+
/** Regex pattern for string validation */
|
|
1792
|
+
pattern?: string;
|
|
1793
|
+
/** Minimum string length */
|
|
1794
|
+
minLength?: number;
|
|
1795
|
+
/** Maximum string length */
|
|
1796
|
+
maxLength?: number;
|
|
1797
|
+
/** Minimum numeric value */
|
|
1798
|
+
min?: number;
|
|
1799
|
+
/** Maximum numeric value */
|
|
1800
|
+
max?: number;
|
|
1801
|
+
/** Custom validator function name */
|
|
1802
|
+
custom?: string;
|
|
1803
|
+
/** Custom validation error message */
|
|
1804
|
+
message?: string;
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1807
|
+
/**
|
|
1808
|
+
* Custom validator function type
|
|
1809
|
+
*/
|
|
1810
|
+
export declare type ValidatorFunction = (value: any) => boolean | Promise<boolean>;
|
|
1811
|
+
|
|
1812
|
+
/**
|
|
1813
|
+
* Verify an authentication event
|
|
1814
|
+
* @param event - Auth event to verify
|
|
1815
|
+
* @param expectedChallenge - Expected challenge string
|
|
1816
|
+
* @param maxAgeSeconds - Maximum age of the event in seconds (default: 300 = 5 minutes)
|
|
1817
|
+
*/
|
|
1818
|
+
export declare function verifyAuthEvent(event: NostrEvent, expectedChallenge: string, maxAgeSeconds?: number): {
|
|
1819
|
+
valid: boolean;
|
|
1820
|
+
error?: string;
|
|
1821
|
+
};
|
|
1822
|
+
|
|
1823
|
+
/**
|
|
1824
|
+
* Verify a Nostr event Schnorr signature (BIP-340)
|
|
1825
|
+
* @param event - Nostr event object with sig field
|
|
1826
|
+
*/
|
|
1827
|
+
export declare function verifyNostrSignature(event: NostrEvent): boolean;
|
|
1828
|
+
|
|
1829
|
+
export declare interface VerifyResult {
|
|
1830
|
+
success: boolean;
|
|
1831
|
+
/** The profile */
|
|
1832
|
+
profile?: Profile;
|
|
1833
|
+
/** The Nostr identity */
|
|
1834
|
+
nostrIdentity?: NostrIdentity;
|
|
1835
|
+
/** The decrypted keypair (only on success) */
|
|
1836
|
+
keypair?: {
|
|
1837
|
+
pubkey: string;
|
|
1838
|
+
privkey: string;
|
|
1839
|
+
npub: string;
|
|
1840
|
+
nsec: string;
|
|
1841
|
+
};
|
|
1842
|
+
/** Error message if success is false */
|
|
1843
|
+
error?: string;
|
|
1844
|
+
/** Error code for programmatic handling */
|
|
1845
|
+
errorCode?: 'INVALID_TOKEN' | 'EXPIRED_TOKEN' | 'USED_TOKEN' | 'NOT_FOUND';
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
export { }
|