@hauska-sdk/core 0.1.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.
@@ -0,0 +1,362 @@
1
+ # Examples
2
+
3
+ Real-world usage examples for the CNS Protocol Core SDK.
4
+
5
+ ## Complete Flow Examples
6
+
7
+ The SDK includes complete flow examples demonstrating end-to-end usage:
8
+
9
+ ### Architect Invoice Flow
10
+
11
+ Complete flow for an architect invoicing scenario: invoice creation → payment → blueprint transfer.
12
+
13
+ ```typescript
14
+ import { architectInvoiceFlow } from "@hauska-sdk/core/examples/architect-invoice-flow";
15
+
16
+ const result = await architectInvoiceFlow();
17
+ // Returns: { architectWallet, clientWallet, blueprintVDA, invoiceVDA, blueprintCID }
18
+ ```
19
+
20
+ **Flow:**
21
+ 1. Architect creates invoice and uploads blueprint
22
+ 2. Client makes payment
23
+ 3. Payment is verified
24
+ 4. Blueprint VDA is transferred to client
25
+ 5. Client retrieves blueprint
26
+
27
+ ### Data Room Flow
28
+
29
+ Complete flow for creating a data room with access control.
30
+
31
+ ```typescript
32
+ import { dataRoomFlow } from "@hauska-sdk/core/examples/data-room-flow";
33
+
34
+ const result = await dataRoomFlow();
35
+ // Returns: { ownerWallet, buyerWallet, dataRoomVDA, accessPass, documentCID, titleReportCID }
36
+ ```
37
+
38
+ **Flow:**
39
+ 1. Property owner creates data room VDA
40
+ 2. Uploads property documents to IPFS
41
+ 3. Creates access pass for potential buyer
42
+ 4. Buyer accesses documents with access pass
43
+ 5. Owner can revoke access pass
44
+
45
+ ### Healthcare Patient Flow
46
+
47
+ Complete flow for healthcare patient record management.
48
+
49
+ ```typescript
50
+ import { healthcarePatientFlow } from "@hauska-sdk/core/examples/healthcare-patient-flow";
51
+
52
+ const result = await healthcarePatientFlow();
53
+ // Returns: { patientWallet, doctorWallet, healthRecordVDA, accessPass, recordsCID, totalRecords }
54
+ ```
55
+
56
+ **Flow:**
57
+ 1. Patient creates health record VDA
58
+ 2. Uploads encrypted medical records
59
+ 3. Grants doctor temporary access (24 hours)
60
+ 4. Doctor accesses records with access pass
61
+ 5. Search all records for patient
62
+
63
+ ### Real Estate Property Flow
64
+
65
+ Complete flow for a real estate property transaction.
66
+
67
+ ```typescript
68
+ import { realEstatePropertyFlow } from "@hauska-sdk/core/examples/real-estate-property-flow";
69
+
70
+ const result = await realEstatePropertyFlow();
71
+ // Returns: { ownerWallet, buyerWallet, propertyVDA, viewingAccessPass, purchasePayment, transferredProperty, documentCID, searchResults }
72
+ ```
73
+
74
+ **Flow:**
75
+ 1. Property owner lists property
76
+ 2. Buyer views property (creates data room access)
77
+ 3. Buyer makes payment
78
+ 4. Property VDA is transferred to buyer
79
+ 5. Buyer now owns the property VDA
80
+ 6. Search property by address
81
+
82
+ ## Common Patterns
83
+
84
+ ### Pattern 1: Create and Share Document
85
+
86
+ ```typescript
87
+ // 1. Create data room with document
88
+ const dataRoom = await sdk.createDataRoom({
89
+ ownerWallet: { userId: "owner", password: "pass" },
90
+ vdaParams: {
91
+ assetType: "deed",
92
+ address: "123 Main St",
93
+ spoke: "real-estate",
94
+ },
95
+ document: {
96
+ content: Buffer.from("Property documents..."),
97
+ name: "property-deed.pdf",
98
+ encrypt: true,
99
+ },
100
+ });
101
+
102
+ // 2. Create access pass for recipient
103
+ const accessPass = await sdk.getVDASDK().createAccessPass({
104
+ grantorWallet: ownerWallet.address,
105
+ recipientWallet: recipientWallet.address,
106
+ accessibleVDAs: [dataRoom.vda.id],
107
+ permissions: ["view", "download"],
108
+ expiry: Date.now() + 30 * 24 * 3600000, // 30 days
109
+ spoke: "real-estate",
110
+ address: "123 Main St",
111
+ });
112
+
113
+ // 3. Recipient retrieves document
114
+ const document = await sdk.retrieveDocument({
115
+ wallet: { userId: "recipient", password: "pass" },
116
+ cid: dataRoom.document!.cid,
117
+ requiredPermissions: ["view"],
118
+ decrypt: true,
119
+ watermark: true, // Watermarked for access pass viewer
120
+ });
121
+ ```
122
+
123
+ ### Pattern 2: Purchase and Transfer
124
+
125
+ ```typescript
126
+ // 1. Purchase and mint VDA
127
+ const purchase = await sdk.purchaseAndMintVDA({
128
+ wallet: { userId: "buyer", password: "pass" },
129
+ amount: "5000",
130
+ currency: "USDC",
131
+ method: "crypto",
132
+ vdaParams: {
133
+ assetType: "blueprint",
134
+ address: "123 Main St",
135
+ spoke: "architect",
136
+ },
137
+ });
138
+
139
+ // 2. Transfer VDA to buyer
140
+ await sdk.getVDASDK().transferOwnership({
141
+ vdaId: originalVDA.id,
142
+ currentOwner: sellerWallet.address,
143
+ newOwner: buyerWallet.address,
144
+ });
145
+ ```
146
+
147
+ ### Pattern 3: Search and Filter
148
+
149
+ ```typescript
150
+ // Search by address
151
+ const results = await sdk.getVDASDK().searchByAddress("Main St", {
152
+ limit: 10,
153
+ offset: 0,
154
+ });
155
+
156
+ // Search by patient ID
157
+ const patientRecords = await sdk.getVDASDK().searchByPatientId("PATIENT-12345");
158
+
159
+ // Search by API14
160
+ const oilRecords = await sdk.getVDASDK().searchByAPI14("42-123-45678-00-00");
161
+ ```
162
+
163
+ ### Pattern 4: Access Control
164
+
165
+ ```typescript
166
+ // Verify access before retrieving
167
+ const accessVerification = await sdk.getRetrievalSDK().verifyAccess(
168
+ documentCID,
169
+ wallet.address,
170
+ ["view", "download"]
171
+ );
172
+
173
+ if (accessVerification.hasAccess) {
174
+ console.log(`Access granted via: ${accessVerification.accessType}`);
175
+ const document = await sdk.retrieveDocument({
176
+ wallet: { userId: "user", password: "pass" },
177
+ cid: documentCID,
178
+ requiredPermissions: ["view"],
179
+ decrypt: true,
180
+ });
181
+ } else {
182
+ console.log(`Access denied: ${accessVerification.reason}`);
183
+ }
184
+ ```
185
+
186
+ ### Pattern 5: Error Handling
187
+
188
+ ```typescript
189
+ import {
190
+ SDKError,
191
+ PaymentError,
192
+ VDAError,
193
+ RetrievalError,
194
+ isSDKError,
195
+ } from "@hauska-sdk/core";
196
+
197
+ try {
198
+ await sdk.purchaseAndMintVDA({ /* ... */ });
199
+ } catch (error) {
200
+ if (isSDKError(error)) {
201
+ switch (error.code) {
202
+ case "PAYMENT_VERIFICATION_FAILED":
203
+ // Handle payment verification failure
204
+ break;
205
+ case "VDA_NOT_FOUND":
206
+ // Handle VDA not found
207
+ break;
208
+ default:
209
+ console.error("SDK error:", error.message, error.context);
210
+ }
211
+ } else {
212
+ console.error("Unexpected error:", error);
213
+ }
214
+ }
215
+ ```
216
+
217
+ ### Pattern 6: Logging and Monitoring
218
+
219
+ ```typescript
220
+ const sdk = new CNSSDK({
221
+ // ... config
222
+ logHook: (level, message, data) => {
223
+ // Send to your logging service
224
+ logger[level](message, data);
225
+ },
226
+ metricsHook: (event, data) => {
227
+ // Send to your analytics service
228
+ analytics.track(event, {
229
+ ...data,
230
+ timestamp: Date.now(),
231
+ });
232
+ },
233
+ });
234
+ ```
235
+
236
+ ## Integration Examples
237
+
238
+ ### Express.js Integration
239
+
240
+ ```typescript
241
+ import express from "express";
242
+ import { CNSSDK } from "@hauska-sdk/core";
243
+
244
+ const app = express();
245
+ const sdk = new CNSSDK({ /* ... config */ });
246
+
247
+ // Create data room endpoint
248
+ app.post("/api/data-rooms", async (req, res) => {
249
+ try {
250
+ const dataRoom = await sdk.createDataRoom({
251
+ ownerWallet: {
252
+ userId: req.user.id,
253
+ password: req.body.password,
254
+ },
255
+ vdaParams: {
256
+ assetType: "deed",
257
+ address: req.body.address,
258
+ spoke: "real-estate",
259
+ },
260
+ document: {
261
+ content: Buffer.from(req.body.document),
262
+ encrypt: true,
263
+ },
264
+ });
265
+
266
+ res.json({ dataRoom });
267
+ } catch (error) {
268
+ if (isSDKError(error)) {
269
+ res.status(error.statusCode || 500).json({ error: error.message });
270
+ } else {
271
+ res.status(500).json({ error: "Internal server error" });
272
+ }
273
+ }
274
+ });
275
+
276
+ // Retrieve document endpoint
277
+ app.get("/api/documents/:cid", async (req, res) => {
278
+ try {
279
+ const document = await sdk.retrieveDocument({
280
+ wallet: {
281
+ userId: req.user.id,
282
+ password: req.body.password,
283
+ },
284
+ cid: req.params.cid,
285
+ requiredPermissions: ["view"],
286
+ decrypt: true,
287
+ });
288
+
289
+ res.setHeader("Content-Type", "application/pdf");
290
+ res.send(document);
291
+ } catch (error) {
292
+ if (error instanceof RetrievalError) {
293
+ res.status(error.statusCode || 404).json({ error: error.message });
294
+ } else {
295
+ res.status(500).json({ error: "Internal server error" });
296
+ }
297
+ }
298
+ });
299
+ ```
300
+
301
+ ### Next.js API Route
302
+
303
+ ```typescript
304
+ // pages/api/vdas/mint.ts
305
+ import { CNSSDK } from "@hauska-sdk/core";
306
+ import type { NextApiRequest, NextApiResponse } from "next";
307
+
308
+ const sdk = new CNSSDK({ /* ... config */ });
309
+
310
+ export default async function handler(
311
+ req: NextApiRequest,
312
+ res: NextApiResponse
313
+ ) {
314
+ if (req.method !== "POST") {
315
+ return res.status(405).json({ error: "Method not allowed" });
316
+ }
317
+
318
+ try {
319
+ const vda = await sdk.getVDASDK().mint({
320
+ assetType: req.body.assetType,
321
+ ownerWallet: req.body.ownerWallet,
322
+ spoke: req.body.spoke,
323
+ address: req.body.address,
324
+ });
325
+
326
+ res.status(200).json({ vda });
327
+ } catch (error) {
328
+ if (isSDKError(error)) {
329
+ res.status(error.statusCode || 500).json({ error: error.message });
330
+ } else {
331
+ res.status(500).json({ error: "Internal server error" });
332
+ }
333
+ }
334
+ }
335
+ ```
336
+
337
+ ## Running Examples
338
+
339
+ To run the complete flow examples:
340
+
341
+ ```bash
342
+ # Install dependencies
343
+ npm install
344
+
345
+ # Run architect invoice flow
346
+ npx ts-node packages/core/examples/architect-invoice-flow.ts
347
+
348
+ # Run data room flow
349
+ npx ts-node packages/core/examples/data-room-flow.ts
350
+
351
+ # Run healthcare patient flow
352
+ npx ts-node packages/core/examples/healthcare-patient-flow.ts
353
+
354
+ # Run real estate property flow
355
+ npx ts-node packages/core/examples/real-estate-property-flow.ts
356
+ ```
357
+
358
+ ## Next Steps
359
+
360
+ - Read the [API Reference](./api-reference.md) for complete API documentation
361
+ - Check the [Getting Started Guide](./getting-started.md) for setup instructions
362
+ - See [Troubleshooting](./troubleshooting.md) for common issues
@@ -0,0 +1,265 @@
1
+ # Getting Started with CNS Protocol Core SDK
2
+
3
+ This guide will help you get started with the CNS Protocol Core SDK in minutes.
4
+
5
+ ## Prerequisites
6
+
7
+ - Node.js 18+ installed
8
+ - TypeScript 5.3+ (recommended)
9
+ - A Pinata account (for IPFS storage)
10
+ - PostgreSQL database (or use Mock adapter for testing)
11
+ - Base L2 RPC endpoint (for blockchain operations)
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install @hauska-sdk/core
17
+ ```
18
+
19
+ ## Basic Setup
20
+
21
+ ### 1. Install Required Adapters
22
+
23
+ ```bash
24
+ # For production (PostgreSQL)
25
+ npm install @hauska-sdk/adapters-storage-postgres
26
+
27
+ # For testing (Mock)
28
+ npm install @hauska-sdk/adapters-storage-mock
29
+
30
+ # For blockchain operations
31
+ npm install @hauska-sdk/adapters-blockchain-ethers
32
+ ```
33
+
34
+ ### 2. Initialize the SDK
35
+
36
+ ```typescript
37
+ import { CNSSDK } from "@hauska-sdk/core";
38
+ import { PostgreSQLStorageAdapter } from "@hauska-sdk/adapters-storage-postgres";
39
+
40
+ const sdk = new CNSSDK({
41
+ vda: {
42
+ storageAdapter: new PostgreSQLStorageAdapter({
43
+ connectionString: process.env.DATABASE_URL!,
44
+ }),
45
+ },
46
+ payment: {
47
+ storage: new PostgreSQLStorageAdapter({
48
+ connectionString: process.env.DATABASE_URL!,
49
+ }),
50
+ blockchain: {
51
+ chain: "base",
52
+ token: "USDC",
53
+ facilitatorWallet: process.env.FACILITATOR_WALLET!,
54
+ baseRpcUrl: process.env.BASE_RPC_URL!,
55
+ },
56
+ },
57
+ retrieval: {
58
+ pinata: {
59
+ pinataJwt: process.env.PINATA_JWT!,
60
+ pinataGateway: "https://gateway.pinata.cloud",
61
+ },
62
+ },
63
+ });
64
+ ```
65
+
66
+ ### 3. Environment Variables
67
+
68
+ Create a `.env` file:
69
+
70
+ ```env
71
+ # Database
72
+ DATABASE_URL=postgresql://user:password@localhost:5432/cns_protocol
73
+
74
+ # Pinata (IPFS)
75
+ PINATA_JWT=your_pinata_jwt_token
76
+
77
+ # Blockchain
78
+ FACILITATOR_WALLET=0xYourFacilitatorWalletAddress
79
+ BASE_RPC_URL=https://mainnet.base.org
80
+
81
+ # Optional: Logging
82
+ LOG_LEVEL=info
83
+ ```
84
+
85
+ ## Your First VDA
86
+
87
+ Let's create your first Verified Digital Asset:
88
+
89
+ ```typescript
90
+ // Get or create a wallet for the user
91
+ const wallet = await sdk.getOrCreateWallet({
92
+ userId: "user-123",
93
+ password: "secure-password",
94
+ });
95
+
96
+ // Mint a VDA
97
+ const vda = await sdk.getVDASDK().mint({
98
+ assetType: "deed",
99
+ ownerWallet: wallet.address,
100
+ address: "123 Main St, Schertz, TX 78154",
101
+ legalDesc: "Lot 5, Block 3",
102
+ spoke: "real-estate",
103
+ });
104
+
105
+ console.log(`VDA created: ${vda.id}`);
106
+ console.log(`Owner: ${vda.metadata.ownerWallet}`);
107
+ ```
108
+
109
+ ## Your First Data Room
110
+
111
+ Create a data room with an encrypted document:
112
+
113
+ ```typescript
114
+ const dataRoom = await sdk.createDataRoom({
115
+ ownerWallet: {
116
+ userId: "owner-123",
117
+ password: "owner-password",
118
+ },
119
+ vdaParams: {
120
+ assetType: "deed",
121
+ address: "123 Main St, Schertz, TX 78154",
122
+ legalDesc: "Lot 5, Block 3",
123
+ spoke: "real-estate",
124
+ },
125
+ document: {
126
+ content: Buffer.from("Property deed content..."),
127
+ name: "property-deed.pdf",
128
+ encrypt: true, // Encrypt before uploading to IPFS
129
+ },
130
+ });
131
+
132
+ console.log(`Data room VDA: ${dataRoom.vda.id}`);
133
+ console.log(`Document CID: ${dataRoom.document?.cid}`);
134
+ ```
135
+
136
+ ## Grant Access with Access Pass
137
+
138
+ Create an access pass to grant temporary access:
139
+
140
+ ```typescript
141
+ const accessPass = await sdk.getVDASDK().createAccessPass({
142
+ grantorWallet: ownerWallet.address,
143
+ recipientWallet: buyerWallet.address,
144
+ accessibleVDAs: [dataRoom.vda.id],
145
+ permissions: ["view", "download"],
146
+ expiry: Date.now() + 30 * 24 * 3600000, // 30 days
147
+ spoke: "real-estate",
148
+ address: "123 Main St, Schertz, TX 78154",
149
+ });
150
+
151
+ console.log(`Access pass created: ${accessPass.id}`);
152
+ console.log(`Expires: ${new Date(accessPass.metadata.expiry!)}`);
153
+ ```
154
+
155
+ ## Retrieve a Document
156
+
157
+ Retrieve a document with access control:
158
+
159
+ ```typescript
160
+ const document = await sdk.retrieveDocument({
161
+ wallet: {
162
+ userId: "buyer-456",
163
+ password: "buyer-password",
164
+ },
165
+ cid: dataRoom.document!.cid,
166
+ requiredPermissions: ["view"],
167
+ decrypt: true,
168
+ watermark: true, // Watermark for access pass viewers
169
+ });
170
+
171
+ console.log(`Document retrieved: ${document.length} bytes`);
172
+ ```
173
+
174
+ ## Complete Example: Real Estate Flow
175
+
176
+ Here's a complete example of a real estate property flow:
177
+
178
+ ```typescript
179
+ import { CNSSDK } from "@hauska-sdk/core";
180
+ import { PostgreSQLStorageAdapter } from "@hauska-sdk/adapters-storage-postgres";
181
+
182
+ const sdk = new CNSSDK({
183
+ // ... config
184
+ });
185
+
186
+ // 1. Property owner creates data room
187
+ const dataRoom = await sdk.createDataRoom({
188
+ ownerWallet: { userId: "owner", password: "pass" },
189
+ vdaParams: {
190
+ assetType: "deed",
191
+ address: "123 Main St",
192
+ spoke: "real-estate",
193
+ },
194
+ document: {
195
+ content: Buffer.from("Property documents..."),
196
+ encrypt: true,
197
+ },
198
+ });
199
+
200
+ // 2. Create access pass for buyer
201
+ await sdk.getVDASDK().createAccessPass({
202
+ grantorWallet: ownerWallet.address,
203
+ recipientWallet: buyerWallet.address,
204
+ accessibleVDAs: [dataRoom.vda.id],
205
+ permissions: ["view"],
206
+ expiry: Date.now() + 7 * 24 * 3600000, // 7 days
207
+ spoke: "real-estate",
208
+ address: "123 Main St",
209
+ });
210
+
211
+ // 3. Buyer makes payment
212
+ const purchase = await sdk.purchaseAndMintVDA({
213
+ wallet: { userId: "buyer", password: "pass" },
214
+ amount: "250000",
215
+ currency: "USDC",
216
+ method: "crypto",
217
+ vdaParams: {
218
+ assetType: "invoice",
219
+ address: "123 Main St",
220
+ spoke: "real-estate",
221
+ },
222
+ });
223
+
224
+ // 4. Transfer property to buyer
225
+ await sdk.getVDASDK().transferOwnership({
226
+ vdaId: dataRoom.vda.id,
227
+ currentOwner: ownerWallet.address,
228
+ newOwner: buyerWallet.address,
229
+ });
230
+ ```
231
+
232
+ ## Next Steps
233
+
234
+ - Read the [API Reference](./api-reference.md) for complete API documentation
235
+ - Check out [Examples](./examples.md) for more use cases
236
+ - See [Troubleshooting](./troubleshooting.md) for common issues
237
+
238
+ ## Testing
239
+
240
+ For testing, use the Mock storage adapter:
241
+
242
+ ```typescript
243
+ import { MockStorageAdapter } from "@hauska-sdk/adapters-storage-mock";
244
+
245
+ const sdk = new CNSSDK({
246
+ vda: {
247
+ storageAdapter: new MockStorageAdapter(),
248
+ },
249
+ payment: {
250
+ storage: new MockStorageAdapter(),
251
+ },
252
+ retrieval: {
253
+ pinata: {
254
+ pinataJwt: "test-jwt",
255
+ pinataGateway: "https://gateway.pinata.cloud",
256
+ },
257
+ },
258
+ });
259
+ ```
260
+
261
+ ## Need Help?
262
+
263
+ - Check the [Troubleshooting Guide](./troubleshooting.md)
264
+ - Review the [API Reference](./api-reference.md)
265
+ - Open an issue on GitHub