@hypercerts-org/sdk-core 0.4.0-beta.0 → 0.6.0-beta.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.
Files changed (62) hide show
  1. package/README.md +459 -79
  2. package/dist/index.cjs +128 -47
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.ts +28 -9
  5. package/dist/index.mjs +128 -47
  6. package/dist/index.mjs.map +1 -1
  7. package/dist/types.cjs +3 -2
  8. package/dist/types.cjs.map +1 -1
  9. package/dist/types.d.ts +28 -9
  10. package/dist/types.mjs +3 -2
  11. package/dist/types.mjs.map +1 -1
  12. package/package.json +9 -5
  13. package/.turbo/turbo-build.log +0 -328
  14. package/.turbo/turbo-test.log +0 -118
  15. package/CHANGELOG.md +0 -22
  16. package/eslint.config.mjs +0 -22
  17. package/rollup.config.js +0 -75
  18. package/src/auth/OAuthClient.ts +0 -497
  19. package/src/core/SDK.ts +0 -410
  20. package/src/core/config.ts +0 -243
  21. package/src/core/errors.ts +0 -257
  22. package/src/core/interfaces.ts +0 -324
  23. package/src/core/types.ts +0 -281
  24. package/src/errors.ts +0 -57
  25. package/src/index.ts +0 -107
  26. package/src/lexicons.ts +0 -64
  27. package/src/repository/BlobOperationsImpl.ts +0 -199
  28. package/src/repository/CollaboratorOperationsImpl.ts +0 -396
  29. package/src/repository/HypercertOperationsImpl.ts +0 -1146
  30. package/src/repository/LexiconRegistry.ts +0 -332
  31. package/src/repository/OrganizationOperationsImpl.ts +0 -234
  32. package/src/repository/ProfileOperationsImpl.ts +0 -281
  33. package/src/repository/RecordOperationsImpl.ts +0 -340
  34. package/src/repository/Repository.ts +0 -482
  35. package/src/repository/interfaces.ts +0 -897
  36. package/src/repository/types.ts +0 -111
  37. package/src/services/hypercerts/types.ts +0 -87
  38. package/src/storage/InMemorySessionStore.ts +0 -127
  39. package/src/storage/InMemoryStateStore.ts +0 -146
  40. package/src/storage.ts +0 -63
  41. package/src/testing/index.ts +0 -67
  42. package/src/testing/mocks.ts +0 -142
  43. package/src/testing/stores.ts +0 -285
  44. package/src/testing.ts +0 -64
  45. package/src/types.ts +0 -86
  46. package/tests/auth/OAuthClient.test.ts +0 -164
  47. package/tests/core/SDK.test.ts +0 -176
  48. package/tests/core/errors.test.ts +0 -81
  49. package/tests/repository/BlobOperationsImpl.test.ts +0 -154
  50. package/tests/repository/CollaboratorOperationsImpl.test.ts +0 -438
  51. package/tests/repository/HypercertOperationsImpl.test.ts +0 -652
  52. package/tests/repository/LexiconRegistry.test.ts +0 -192
  53. package/tests/repository/OrganizationOperationsImpl.test.ts +0 -242
  54. package/tests/repository/ProfileOperationsImpl.test.ts +0 -254
  55. package/tests/repository/RecordOperationsImpl.test.ts +0 -375
  56. package/tests/repository/Repository.test.ts +0 -149
  57. package/tests/utils/fixtures.ts +0 -117
  58. package/tests/utils/mocks.ts +0 -109
  59. package/tests/utils/repository-fixtures.ts +0 -78
  60. package/tsconfig.json +0 -11
  61. package/tsconfig.tsbuildinfo +0 -1
  62. package/vitest.config.ts +0 -30
package/README.md CHANGED
@@ -1,54 +1,17 @@
1
1
  # @hypercerts-org/sdk-core
2
2
 
3
- Framework-agnostic ATProto SDK for Hypercerts.
3
+ Framework-agnostic ATProto SDK for Hypercerts. Create, manage, and collaborate on hypercerts using the AT Protocol.
4
4
 
5
5
  ```bash
6
6
  pnpm add @hypercerts-org/sdk-core
7
7
  ```
8
8
 
9
- ## Entrypoints
10
-
11
- ```
12
- @hypercerts-org/sdk-core
13
- ├── / → Full SDK (createATProtoSDK, Repository, types, errors)
14
- ├── /types → TypeScript types (re-exported from @hypercerts-org/lexicon)
15
- ├── /errors → Error classes
16
- ├── /lexicons → LexiconRegistry, HYPERCERT_LEXICONS, HYPERCERT_COLLECTIONS
17
- ├── /storage → InMemorySessionStore, InMemoryStateStore
18
- └── /testing → createMockSession, MockSessionStore
19
- ```
20
-
21
- ## Type System
22
-
23
- Types are generated from ATProto lexicon definitions in `@hypercerts-org/lexicon` and re-exported with friendly aliases:
24
-
25
- | Lexicon Type | SDK Alias |
26
- |--------------|-----------|
27
- | `OrgHypercertsClaim.Main` | `HypercertClaim` |
28
- | `OrgHypercertsClaimRights.Main` | `HypercertRights` |
29
- | `OrgHypercertsClaimContribution.Main` | `HypercertContribution` |
30
- | `OrgHypercertsClaimMeasurement.Main` | `HypercertMeasurement` |
31
- | `OrgHypercertsClaimEvaluation.Main` | `HypercertEvaluation` |
32
- | `OrgHypercertsCollection.Main` | `HypercertCollection` |
33
- | `AppCertifiedLocation.Main` | `HypercertLocation` |
34
-
35
- ```typescript
36
- import type { HypercertClaim, HypercertRights } from "@hypercerts-org/sdk-core";
37
-
38
- // For validation functions, import the namespaced types
39
- import { OrgHypercertsClaim } from "@hypercerts-org/sdk-core";
40
-
41
- if (OrgHypercertsClaim.isRecord(data)) {
42
- // data is typed as HypercertClaim
43
- }
44
- ```
45
-
46
- ## Usage
9
+ ## Quick Start
47
10
 
48
11
  ```typescript
49
12
  import { createATProtoSDK } from "@hypercerts-org/sdk-core";
50
13
 
51
- // 1. Create SDK instance
14
+ // 1. Create SDK with OAuth configuration
52
15
  const sdk = createATProtoSDK({
53
16
  oauth: {
54
17
  clientId: "https://your-app.com/client-metadata.json",
@@ -59,85 +22,502 @@ const sdk = createATProtoSDK({
59
22
  },
60
23
  });
61
24
 
62
- // 2. Start OAuth flow → redirect user to authUrl
25
+ // 2. Authenticate user
63
26
  const authUrl = await sdk.authorize("user.bsky.social");
27
+ // Redirect user to authUrl...
28
+
29
+ // 3. Handle OAuth callback
30
+ const session = await sdk.callback(callbackParams);
31
+
32
+ // 4. Get repository and start creating hypercerts
33
+ const repo = sdk.getRepository(session);
34
+ const claim = await repo.hypercerts.create({
35
+ title: "Tree Planting Initiative 2025",
36
+ description: "Planted 1000 trees in the rainforest",
37
+ impact: {
38
+ scope: ["Environmental Conservation"],
39
+ work: { from: "2025-01-01", to: "2025-12-31" },
40
+ contributors: ["did:plc:contributor1"],
41
+ },
42
+ });
43
+ ```
44
+
45
+ ## Core Concepts
46
+
47
+ ### 1. Authentication
48
+
49
+ The SDK uses OAuth 2.0 for authentication with support for both PDS (Personal Data Server) and SDS (Shared Data Server).
50
+
51
+ ```typescript
52
+ // First-time user authentication
53
+ const authUrl = await sdk.authorize("user.bsky.social");
54
+ // Redirect user to authUrl to complete OAuth flow
55
+
56
+ // Handle the OAuth callback
57
+ const session = await sdk.callback({
58
+ code: "...",
59
+ state: "...",
60
+ iss: "...",
61
+ });
64
62
 
65
- // 3. Handle callback at redirectUri → exchange code for session
66
- const session = await sdk.callback(params); // params from callback URL
63
+ // Restore existing session for returning users
64
+ const session = await sdk.restoreSession("did:plc:user123");
67
65
 
68
- // 4. Use session to interact with repositories
66
+ // Get repository for authenticated user
69
67
  const repo = sdk.getRepository(session);
70
- await repo.hypercerts.create({ title: "My Hypercert", ... });
68
+ ```
69
+
70
+ ### 2. Working with Hypercerts
71
+
72
+ #### Creating a Hypercert
73
+
74
+ ```typescript
75
+ const hypercert = await repo.hypercerts.create({
76
+ title: "Climate Research Project",
77
+ description: "Research on carbon capture technologies",
78
+ image: imageBlob, // optional: File or Blob
79
+ externalUrl: "https://example.com/project",
80
+
81
+ impact: {
82
+ scope: ["Climate Change", "Carbon Capture"],
83
+ work: {
84
+ from: "2024-01-01",
85
+ to: "2025-12-31",
86
+ },
87
+ contributors: ["did:plc:researcher1", "did:plc:researcher2"],
88
+ },
89
+
90
+ rights: {
91
+ license: "CC-BY-4.0",
92
+ allowsDerivatives: true,
93
+ transferrable: false,
94
+ },
95
+ });
96
+
97
+ console.log("Created hypercert:", hypercert.uri);
98
+ ```
99
+
100
+ #### Retrieving Hypercerts
101
+
102
+ ```typescript
103
+ // Get a specific hypercert by URI
104
+ const hypercert = await repo.hypercerts.get(
105
+ "at://did:plc:user123/org.hypercerts.claim/abc123"
106
+ );
107
+
108
+ // List all hypercerts in the repository
109
+ const { records } = await repo.hypercerts.list();
110
+ for (const claim of records) {
111
+ console.log(claim.value.title);
112
+ }
71
113
 
72
- // For returning users, restore session by DID
73
- const existingSession = await sdk.restoreSession("did:plc:...");
114
+ // List with pagination
115
+ const { records, cursor } = await repo.hypercerts.list({ limit: 10 });
116
+ if (cursor) {
117
+ const nextPage = await repo.hypercerts.list({ limit: 10, cursor });
118
+ }
74
119
  ```
75
120
 
76
- ## Repository API
121
+ #### Updating a Hypercert
77
122
 
123
+ ```typescript
124
+ // Update an existing hypercert
125
+ await repo.hypercerts.update(
126
+ "at://did:plc:user123/org.hypercerts.claim/abc123",
127
+ {
128
+ title: "Updated Climate Research Project",
129
+ description: "Expanded scope to include renewable energy",
130
+ impact: {
131
+ scope: ["Climate Change", "Carbon Capture", "Renewable Energy"],
132
+ work: { from: "2024-01-01", to: "2026-12-31" },
133
+ contributors: ["did:plc:researcher1", "did:plc:researcher2"],
134
+ },
135
+ }
136
+ );
78
137
  ```
79
- repo
80
- ├── .records → create, get, update, delete, list
81
- ├── .blobs → upload, get
82
- ├── .profile → get, update (PDS only)
83
- ├── .hypercerts → create, get, update, delete, list, addContribution, addMeasurement
84
- ├── .collaborators → grant, revoke, list, hasAccess, getRole, getPermissions, transferOwnership (SDS only)
85
- └── .organizations → create, get, list (SDS only)
138
+
139
+ #### Deleting a Hypercert
140
+
141
+ ```typescript
142
+ await repo.hypercerts.delete(
143
+ "at://did:plc:user123/org.hypercerts.claim/abc123"
144
+ );
86
145
  ```
87
146
 
88
- ### Collaborator Operations (SDS only)
147
+ ### 3. Contributions and Measurements
148
+
149
+ #### Adding Contributions
150
+
151
+ ```typescript
152
+ // Add a contribution to a hypercert
153
+ const contribution = await repo.hypercerts.addContribution({
154
+ claim: "at://did:plc:user123/org.hypercerts.claim/abc123",
155
+ contributor: "did:plc:contributor456",
156
+ description: "Led the research team and conducted field studies",
157
+ contributionType: "Work",
158
+ percentage: 40.0,
159
+ });
160
+ ```
161
+
162
+ #### Adding Measurements
163
+
164
+ ```typescript
165
+ // Add a measurement/evaluation
166
+ const measurement = await repo.hypercerts.addMeasurement({
167
+ claim: "at://did:plc:user123/org.hypercerts.claim/abc123",
168
+ type: "Impact",
169
+ value: 1000,
170
+ unit: "trees planted",
171
+ verifiedBy: "did:plc:auditor789",
172
+ verificationMethod: "On-site inspection with GPS verification",
173
+ measuredAt: new Date().toISOString(),
174
+ });
175
+ ```
176
+
177
+ ### 4. Blob Operations (Images & Files)
178
+
179
+ ```typescript
180
+ // Upload an image or file
181
+ const blobResult = await repo.blobs.upload(imageFile);
182
+ console.log("Blob uploaded:", blobResult.ref.$link);
183
+
184
+ // Download a blob
185
+ const blobData = await repo.blobs.get(
186
+ "did:plc:user123",
187
+ "bafyreiabc123..."
188
+ );
189
+ ```
190
+
191
+ ### 5. Organizations (SDS only)
192
+
193
+ Organizations allow multiple users to collaborate on shared repositories.
194
+
195
+ ```typescript
196
+ // Create an organization
197
+ const org = await repo.organizations.create({
198
+ name: "Climate Research Institute",
199
+ description: "Leading research on climate solutions",
200
+ handle: "climate-research", // optional: unique handle
201
+ });
202
+
203
+ console.log("Organization DID:", org.did);
204
+
205
+ // List all organizations you belong to
206
+ const { organizations } = await repo.organizations.list();
207
+ for (const org of organizations) {
208
+ console.log(`${org.name} (${org.role})`);
209
+ }
210
+
211
+ // List with pagination
212
+ const { organizations, cursor } = await repo.organizations.list({ limit: 10 });
213
+
214
+ // Get a specific organization
215
+ const org = await repo.organizations.get("did:plc:org123");
216
+ console.log(`${org.name} - ${org.description}`);
217
+ ```
218
+
219
+ ### 6. Collaborator Management (SDS only)
220
+
221
+ Manage who has access to your repository and what they can do.
222
+
223
+ #### Granting Access
89
224
 
90
225
  ```typescript
91
- // Grant access to a user
226
+ // Grant different levels of access
92
227
  await repo.collaborators.grant({
93
228
  userDid: "did:plc:user123",
94
229
  role: "editor", // viewer | editor | admin | owner
95
230
  });
96
231
 
97
- // Revoke access
98
- await repo.collaborators.revoke({ userDid: "did:plc:user123" });
232
+ // Roles explained:
233
+ // - viewer: Read-only access
234
+ // - editor: Can create and edit records
235
+ // - admin: Can manage collaborators and settings
236
+ // - owner: Full control (same as repository owner)
237
+ ```
238
+
239
+ #### Managing Collaborators
240
+
241
+ ```typescript
242
+ // List all collaborators with pagination
243
+ const { collaborators, cursor } = await repo.collaborators.list();
244
+ for (const collab of collaborators) {
245
+ console.log(`${collab.userDid} - ${collab.role}`);
246
+ }
99
247
 
100
- // List all collaborators
101
- const collaborators = await repo.collaborators.list();
248
+ // List next page
249
+ if (cursor) {
250
+ const nextPage = await repo.collaborators.list({ cursor, limit: 20 });
251
+ }
102
252
 
103
- // Check if user has access
253
+ // Check if a user has access
104
254
  const hasAccess = await repo.collaborators.hasAccess("did:plc:user123");
105
255
 
106
- // Get user's role
256
+ // Get a specific user's role
107
257
  const role = await repo.collaborators.getRole("did:plc:user123");
258
+ console.log(`User role: ${role}`); // "editor", "admin", etc.
108
259
 
109
260
  // Get current user's permissions
110
261
  const permissions = await repo.collaborators.getPermissions();
111
262
  if (permissions.admin) {
112
- // Can manage collaborators
263
+ console.log("You can manage collaborators");
113
264
  }
265
+ if (permissions.create) {
266
+ console.log("You can create records");
267
+ }
268
+ ```
269
+
270
+ #### Revoking Access
271
+
272
+ ```typescript
273
+ // Remove a collaborator
274
+ await repo.collaborators.revoke({
275
+ userDid: "did:plc:user123",
276
+ });
277
+ ```
278
+
279
+ #### Transferring Ownership
114
280
 
115
- // Transfer ownership (irreversible!)
281
+ ```typescript
282
+ // Transfer repository ownership (irreversible!)
116
283
  await repo.collaborators.transferOwnership({
117
- newOwnerDid: "did:plc:new-owner",
284
+ newOwnerDid: "did:plc:newowner456",
118
285
  });
119
286
  ```
120
287
 
121
- ### SDS vs PDS Operations
288
+ ### 7. Generic Record Operations
289
+
290
+ For working with any ATProto record type:
291
+
292
+ ```typescript
293
+ // Create a generic record
294
+ const record = await repo.records.create({
295
+ collection: "org.hypercerts.claim",
296
+ record: {
297
+ $type: "org.hypercerts.claim",
298
+ title: "My Claim",
299
+ // ... record data
300
+ },
301
+ });
122
302
 
123
- | Operation | PDS | SDS | Namespace |
124
- |-----------|-----|-----|-----------|
125
- | Records (CRUD) | ✅ | ✅ | `com.atproto.repo.*` |
126
- | Blobs | ✅ | ✅ | `com.atproto.repo.uploadBlob`, `com.atproto.sync.getBlob` |
127
- | Profile | ✅ | ❌ | `app.bsky.actor.profile` |
128
- | Organizations | ❌ | ✅ | `com.sds.organization.*` |
129
- | Collaborators | ❌ | ✅ | `com.sds.repo.*` |
303
+ // Get a record
304
+ const record = await repo.records.get({
305
+ collection: "org.hypercerts.claim",
306
+ rkey: "abc123",
307
+ });
130
308
 
131
- ## Errors
309
+ // Update a record
310
+ await repo.records.update({
311
+ collection: "org.hypercerts.claim",
312
+ rkey: "abc123",
313
+ record: {
314
+ $type: "org.hypercerts.claim",
315
+ title: "Updated Title",
316
+ // ... updated data
317
+ },
318
+ });
319
+
320
+ // Delete a record
321
+ await repo.records.delete({
322
+ collection: "org.hypercerts.claim",
323
+ rkey: "abc123",
324
+ });
325
+
326
+ // List records with pagination
327
+ const { records, cursor } = await repo.records.list({
328
+ collection: "org.hypercerts.claim",
329
+ limit: 50,
330
+ });
331
+ ```
332
+
333
+ ### 8. Profile Management (PDS only)
132
334
 
133
335
  ```typescript
134
- import { ValidationError, NetworkError, AuthenticationError } from "@hypercerts-org/sdk-core/errors";
336
+ // Get user profile
337
+ const profile = await repo.profile.get();
338
+ console.log(`${profile.displayName} (@${profile.handle})`);
339
+
340
+ // Update profile
341
+ await repo.profile.update({
342
+ displayName: "Jane Researcher",
343
+ description: "Climate scientist and hypercert enthusiast",
344
+ avatar: avatarBlob, // optional
345
+ banner: bannerBlob, // optional
346
+ });
347
+ ```
348
+
349
+ ## API Reference
350
+
351
+ ### Repository Operations
352
+
353
+ | Operation | Method | PDS | SDS | Returns |
354
+ |-----------|--------|-----|-----|---------|
355
+ | **Records** | | | | |
356
+ | Create record | `repo.records.create()` | ✅ | ✅ | `{ uri, cid }` |
357
+ | Get record | `repo.records.get()` | ✅ | ✅ | Record data |
358
+ | Update record | `repo.records.update()` | ✅ | ✅ | `{ uri, cid }` |
359
+ | Delete record | `repo.records.delete()` | ✅ | ✅ | void |
360
+ | List records | `repo.records.list()` | ✅ | ✅ | `{ records, cursor? }` |
361
+ | **Hypercerts** | | | | |
362
+ | Create hypercert | `repo.hypercerts.create()` | ✅ | ✅ | `{ uri, cid, value }` |
363
+ | Get hypercert | `repo.hypercerts.get()` | ✅ | ✅ | Full hypercert |
364
+ | Update hypercert | `repo.hypercerts.update()` | ✅ | ✅ | `{ uri, cid }` |
365
+ | Delete hypercert | `repo.hypercerts.delete()` | ✅ | ✅ | void |
366
+ | List hypercerts | `repo.hypercerts.list()` | ✅ | ✅ | `{ records, cursor? }` |
367
+ | Add contribution | `repo.hypercerts.addContribution()` | ✅ | ✅ | Contribution |
368
+ | Add measurement | `repo.hypercerts.addMeasurement()` | ✅ | ✅ | Measurement |
369
+ | **Blobs** | | | | |
370
+ | Upload blob | `repo.blobs.upload()` | ✅ | ✅ | `{ ref, mimeType, size }` |
371
+ | Get blob | `repo.blobs.get()` | ✅ | ✅ | Blob data |
372
+ | **Profile** | | | | |
373
+ | Get profile | `repo.profile.get()` | ✅ | ❌ | Profile data |
374
+ | Update profile | `repo.profile.update()` | ✅ | ❌ | void |
375
+ | **Organizations** | | | | |
376
+ | Create org | `repo.organizations.create()` | ❌ | ✅ | `{ did, name, ... }` |
377
+ | Get org | `repo.organizations.get()` | ❌ | ✅ | Organization |
378
+ | List orgs | `repo.organizations.list()` | ❌ | ✅ | `{ organizations, cursor? }` |
379
+ | **Collaborators** | | | | |
380
+ | Grant access | `repo.collaborators.grant()` | ❌ | ✅ | void |
381
+ | Revoke access | `repo.collaborators.revoke()` | ❌ | ✅ | void |
382
+ | List collaborators | `repo.collaborators.list()` | ❌ | ✅ | `{ collaborators, cursor? }` |
383
+ | Check access | `repo.collaborators.hasAccess()` | ❌ | ✅ | boolean |
384
+ | Get role | `repo.collaborators.getRole()` | ❌ | ✅ | Role string |
385
+ | Get permissions | `repo.collaborators.getPermissions()` | ❌ | ✅ | Permissions |
386
+ | Transfer ownership | `repo.collaborators.transferOwnership()` | ❌ | ✅ | void |
387
+
388
+ ## Type System
389
+
390
+ Types are generated from ATProto lexicon definitions and exported with friendly aliases:
391
+
392
+ ```typescript
393
+ import type {
394
+ HypercertClaim,
395
+ HypercertRights,
396
+ HypercertContribution,
397
+ HypercertMeasurement,
398
+ HypercertEvaluation,
399
+ HypercertCollection,
400
+ HypercertLocation,
401
+ } from "@hypercerts-org/sdk-core";
402
+
403
+ // For validation, use namespaced imports
404
+ import { OrgHypercertsClaim } from "@hypercerts-org/sdk-core";
405
+
406
+ if (OrgHypercertsClaim.isRecord(data)) {
407
+ // data is typed as HypercertClaim
408
+ }
409
+ ```
410
+
411
+ | Lexicon Type | SDK Alias |
412
+ |--------------|-----------|
413
+ | `OrgHypercertsClaim.Main` | `HypercertClaim` |
414
+ | `OrgHypercertsClaimRights.Main` | `HypercertRights` |
415
+ | `OrgHypercertsClaimContribution.Main` | `HypercertContribution` |
416
+ | `OrgHypercertsClaimMeasurement.Main` | `HypercertMeasurement` |
417
+ | `OrgHypercertsClaimEvaluation.Main` | `HypercertEvaluation` |
418
+ | `OrgHypercertsCollection.Main` | `HypercertCollection` |
419
+ | `AppCertifiedLocation.Main` | `HypercertLocation` |
420
+
421
+ ## Error Handling
422
+
423
+ ```typescript
424
+ import {
425
+ ValidationError,
426
+ NetworkError,
427
+ AuthenticationError,
428
+ SDSRequiredError,
429
+ } from "@hypercerts-org/sdk-core/errors";
430
+
431
+ try {
432
+ await repo.hypercerts.create({ ... });
433
+ } catch (error) {
434
+ if (error instanceof ValidationError) {
435
+ console.error("Invalid hypercert data:", error.message);
436
+ } else if (error instanceof NetworkError) {
437
+ console.error("Network issue:", error.message);
438
+ } else if (error instanceof AuthenticationError) {
439
+ console.error("Authentication failed:", error.message);
440
+ } else if (error instanceof SDSRequiredError) {
441
+ console.error("This operation requires SDS:", error.message);
442
+ }
443
+ }
444
+ ```
445
+
446
+ ## Package Entrypoints
447
+
448
+ ```
449
+ @hypercerts-org/sdk-core
450
+ ├── / → Full SDK (createATProtoSDK, Repository, types, errors)
451
+ ├── /types → TypeScript types (re-exported from @hypercerts-org/lexicon)
452
+ ├── /errors → Error classes
453
+ ├── /lexicons → LexiconRegistry, HYPERCERT_LEXICONS, HYPERCERT_COLLECTIONS
454
+ ├── /storage → InMemorySessionStore, InMemoryStateStore
455
+ └── /testing → createMockSession, MockSessionStore
456
+ ```
457
+
458
+ ## Advanced Usage
459
+
460
+ ### Custom Session Storage
461
+
462
+ ```typescript
463
+ import { createATProtoSDK } from "@hypercerts-org/sdk-core";
464
+ import { InMemorySessionStore } from "@hypercerts-org/sdk-core/storage";
465
+
466
+ const sdk = createATProtoSDK({
467
+ oauth: { ... },
468
+ sessionStore: new InMemorySessionStore(),
469
+ });
470
+ ```
471
+
472
+ ### Testing with Mocks
473
+
474
+ ```typescript
475
+ import { createMockSession, MockSessionStore } from "@hypercerts-org/sdk-core/testing";
476
+
477
+ const mockSession = createMockSession({
478
+ did: "did:plc:test123",
479
+ handle: "test.user",
480
+ });
481
+
482
+ const mockStore = new MockSessionStore();
483
+ await mockStore.set(mockSession);
484
+ ```
485
+
486
+ ### Working with Lexicons
487
+
488
+ ```typescript
489
+ import {
490
+ LexiconRegistry,
491
+ HYPERCERT_LEXICONS,
492
+ HYPERCERT_COLLECTIONS,
493
+ } from "@hypercerts-org/sdk-core/lexicons";
494
+
495
+ const registry = new LexiconRegistry();
496
+ registry.registerLexicons(HYPERCERT_LEXICONS);
497
+
498
+ // Validate a record
499
+ const isValid = registry.validate(
500
+ "org.hypercerts.claim",
501
+ claimData
502
+ );
135
503
  ```
136
504
 
137
505
  ## Development
138
506
 
139
507
  ```bash
140
- pnpm build # Build
141
- pnpm test # Test
142
- pnpm test:coverage # Coverage
508
+ pnpm install # Install dependencies
509
+ pnpm build # Build the package
510
+ pnpm test # Run tests
511
+ pnpm test:coverage # Run tests with coverage
512
+ pnpm test:watch # Run tests in watch mode
143
513
  ```
514
+
515
+ ## License
516
+
517
+ MIT
518
+
519
+ ## Resources
520
+
521
+ - [ATProto Documentation](https://atproto.com/docs)
522
+ - [Hypercerts Documentation](https://hypercerts.org)
523
+ - [GitHub Repository](https://github.com/hypercerts-org/hypercerts-sdk)