@opendatalabs/vana-sdk 0.1.0-alpha.5869423
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/LICENSE +15 -0
- package/README.md +600 -0
- package/dist/index.browser.d.ts +31228 -0
- package/dist/index.browser.js +40628 -0
- package/dist/index.browser.js.map +1 -0
- package/dist/index.d.cts +31192 -0
- package/dist/index.node.cjs +40692 -0
- package/dist/index.node.cjs.map +1 -0
- package/dist/index.node.d.cts +31294 -0
- package/dist/index.node.d.ts +31294 -0
- package/dist/index.node.js +40563 -0
- package/dist/index.node.js.map +1 -0
- package/package.json +90 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025, Vana
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,600 @@
|
|
|
1
|
+
# Vana SDK
|
|
2
|
+
|
|
3
|
+
The Vana SDK is a comprehensive TypeScript library for building applications on the Vana Network. It provides simple, powerful APIs for gasless data permissions, file management, and secure data portability.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/vana-sdk)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
[](https://opensource.org/licenses/ISC)
|
|
8
|
+
|
|
9
|
+
[Documentation](https://vana-com.github.io/vana-sdk) • [Examples](#examples) • [API Reference](https://vana-com.github.io/vana-sdk)
|
|
10
|
+
|
|
11
|
+
## Why Vana SDK?
|
|
12
|
+
|
|
13
|
+
- **🔐 Gasless Permissions**: EIP-712 based permission system with zero gas fees for users
|
|
14
|
+
- **📁 Data Management**: Query, upload, and manage encrypted user data files
|
|
15
|
+
- **🔄 Flexible Relaying**: Callback-based relay system supporting any gasless transaction infrastructure
|
|
16
|
+
- **📊 Schema Validation**: Built-in JSON Schema and SQLite schema validation with AJV
|
|
17
|
+
- **🔧 Type-Safe**: Full TypeScript support with comprehensive type definitions
|
|
18
|
+
- **🎯 Production Ready**: Battle-tested with comprehensive error handling and retry mechanisms
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# npm
|
|
24
|
+
npm install vana-sdk
|
|
25
|
+
|
|
26
|
+
# yarn
|
|
27
|
+
yarn add vana-sdk
|
|
28
|
+
|
|
29
|
+
# pnpm
|
|
30
|
+
pnpm add vana-sdk
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Peer Dependencies:**
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install viem@^2.31.7
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
### Basic Setup
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { Vana } from "vana-sdk";
|
|
45
|
+
import { createWalletClient, http } from "viem";
|
|
46
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
47
|
+
import { mokshaTestnet } from "vana-sdk";
|
|
48
|
+
|
|
49
|
+
// Create wallet client
|
|
50
|
+
const account = privateKeyToAccount("0x...");
|
|
51
|
+
const walletClient = createWalletClient({
|
|
52
|
+
account,
|
|
53
|
+
chain: mokshaTestnet,
|
|
54
|
+
transport: http("https://rpc.moksha.vana.org"),
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Initialize Vana SDK
|
|
58
|
+
const vana = new Vana({
|
|
59
|
+
walletClient,
|
|
60
|
+
// Optional: configure gasless relayer
|
|
61
|
+
relayerUrl: "https://relayer.moksha.vana.org",
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Grant Data Permission (Gasless)
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
// Grant permission for an AI application to access user data
|
|
69
|
+
const txHash = await vana.permissions.grant({
|
|
70
|
+
to: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36", // Application address
|
|
71
|
+
operation: "llm_inference",
|
|
72
|
+
parameters: {
|
|
73
|
+
prompt: "Analyze my browsing data for insights",
|
|
74
|
+
maxTokens: 1000,
|
|
75
|
+
files: [12, 15, 28], // Specific file IDs
|
|
76
|
+
model: "gpt-4",
|
|
77
|
+
},
|
|
78
|
+
expiresAt: Math.floor(Date.now() / 1000) + 24 * 60 * 60, // 24 hours
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
console.log("Permission granted:", txHash);
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Query User Data Files
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
// Get all files owned by a user
|
|
88
|
+
const files = await vana.data.getUserFiles({
|
|
89
|
+
user: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36",
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
files.forEach((file) => {
|
|
93
|
+
console.log(`File ${file.id}: ${file.url}`);
|
|
94
|
+
console.log(`Schema: ${file.schemaId}, Added: ${file.addedAtBlock}`);
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Upload Encrypted File
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
// Generate encryption key from wallet
|
|
102
|
+
const encryptionKey = await generateEncryptionKey(walletClient);
|
|
103
|
+
|
|
104
|
+
// Encrypt user data
|
|
105
|
+
const userData = new Blob([
|
|
106
|
+
JSON.stringify({
|
|
107
|
+
browsing_history: [{ url: "https://example.com", timestamp: Date.now() }],
|
|
108
|
+
}),
|
|
109
|
+
]);
|
|
110
|
+
|
|
111
|
+
const encryptedData = await encryptUserData(userData, encryptionKey);
|
|
112
|
+
|
|
113
|
+
// Upload to IPFS and register on-chain
|
|
114
|
+
const result = await vana.data.uploadEncryptedFile({
|
|
115
|
+
data: encryptedData,
|
|
116
|
+
schemaId: 123, // JSON schema for browsing data
|
|
117
|
+
filename: "browsing-data.json",
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
console.log("File uploaded:", result.fileId, result.url);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Architecture
|
|
124
|
+
|
|
125
|
+
The Vana SDK follows a resource-oriented architecture with five main controllers:
|
|
126
|
+
|
|
127
|
+
### Core Controllers
|
|
128
|
+
|
|
129
|
+
| Controller | Purpose | Key Methods |
|
|
130
|
+
| ---------------------- | --------------------------------------- | ----------------------------------------------------------------- |
|
|
131
|
+
| **`vana.permissions`** | Gasless permission grants & revocations | `grant()`, `revoke()`, `getUserPermissions()` |
|
|
132
|
+
| **`vana.data`** | Data file management & encryption | `getUserFiles()`, `uploadEncryptedFile()`, `validateDataSchema()` |
|
|
133
|
+
| **`vana.server`** | Trusted server management | `trustServer()`, `untrustServer()`, `processWithTrustedServer()` |
|
|
134
|
+
| **`vana.protocol`** | Low-level contract access | `getContract()`, `getAvailableContracts()` |
|
|
135
|
+
|
|
136
|
+
### Configuration Options
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
const vana = new Vana({
|
|
140
|
+
// Required: Wallet client for signing
|
|
141
|
+
walletClient,
|
|
142
|
+
|
|
143
|
+
// Optional: Gasless transaction relay
|
|
144
|
+
relayerUrl: "https://custom-relayer.com",
|
|
145
|
+
|
|
146
|
+
// Optional: Custom callback-based relaying
|
|
147
|
+
relayerCallbacks: {
|
|
148
|
+
submitPermissionGrant: async (typedData, signature) => {
|
|
149
|
+
// Custom relay implementation
|
|
150
|
+
return await customRelayer.submit(typedData, signature);
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
// Optional: Storage configuration
|
|
155
|
+
storageManager: new StorageManager({
|
|
156
|
+
defaultProvider: "ipfs",
|
|
157
|
+
providers: {
|
|
158
|
+
ipfs: new PinataStorage({ apiKey: "...", secretKey: "..." }),
|
|
159
|
+
},
|
|
160
|
+
}),
|
|
161
|
+
|
|
162
|
+
// Optional: Subgraph for efficient data queries
|
|
163
|
+
subgraphUrl: "https://api.thegraph.com/subgraphs/name/vana/moksha",
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Core Concepts
|
|
168
|
+
|
|
169
|
+
### Gasless Permissions
|
|
170
|
+
|
|
171
|
+
The Vana SDK enables applications to request data access permissions without users paying gas fees:
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
// Complete gasless permission flow
|
|
175
|
+
const permission = await vana.permissions.grant({
|
|
176
|
+
to: applicationAddress,
|
|
177
|
+
operation: "data_analysis",
|
|
178
|
+
parameters: {
|
|
179
|
+
// Structured parameters for the operation
|
|
180
|
+
analysisType: "sentiment",
|
|
181
|
+
outputFormat: "json",
|
|
182
|
+
maxDataPoints: 1000,
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// The SDK handles:
|
|
187
|
+
// 1. Parameter serialization & IPFS storage
|
|
188
|
+
// 2. EIP-712 typed data creation
|
|
189
|
+
// 3. User signature via wallet
|
|
190
|
+
// 4. Relayer submission & gas payment
|
|
191
|
+
// 5. On-chain permission registration
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Data File Management
|
|
195
|
+
|
|
196
|
+
Query and manage encrypted user data files using the subgraph for efficiency:
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
// Efficiently query user files (no contract scanning)
|
|
200
|
+
const files = await vana.data.getUserFiles({
|
|
201
|
+
user: userAddress,
|
|
202
|
+
// Optional: override subgraph URL
|
|
203
|
+
subgraphUrl: "https://custom-subgraph.com/graphql",
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// Files are automatically deduplicated by ID
|
|
207
|
+
// Latest timestamp wins for duplicate file IDs
|
|
208
|
+
console.log(`Found ${files.length} unique files`);
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Schema Validation
|
|
212
|
+
|
|
213
|
+
Built-in support for validating data schemas and user data:
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
// Validate a data schema against Vana meta-schema
|
|
217
|
+
const schema = {
|
|
218
|
+
name: "Instagram Export",
|
|
219
|
+
version: "1.0.0",
|
|
220
|
+
dialect: "json",
|
|
221
|
+
schema: {
|
|
222
|
+
type: "object",
|
|
223
|
+
properties: {
|
|
224
|
+
posts: { type: "array" },
|
|
225
|
+
profile: { type: "object" },
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
vana.data.validateDataSchema(schema);
|
|
231
|
+
|
|
232
|
+
// Validate user data against the schema
|
|
233
|
+
const userData = { posts: [], profile: { username: "alice" } };
|
|
234
|
+
vana.data.validateDataAgainstSchema(userData, schema);
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Flexible Relay System
|
|
238
|
+
|
|
239
|
+
Configure gasless transactions using callbacks instead of fixed HTTP APIs:
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
const vana = new Vana({
|
|
243
|
+
walletClient,
|
|
244
|
+
relayerCallbacks: {
|
|
245
|
+
// Custom permission grant relaying
|
|
246
|
+
submitPermissionGrant: async (typedData, signature) => {
|
|
247
|
+
const response = await fetch("/api/relay/grant", {
|
|
248
|
+
method: "POST",
|
|
249
|
+
body: JSON.stringify({ typedData, signature }),
|
|
250
|
+
});
|
|
251
|
+
const result = await response.json();
|
|
252
|
+
return result.transactionHash;
|
|
253
|
+
},
|
|
254
|
+
|
|
255
|
+
// Custom revocation relaying
|
|
256
|
+
submitPermissionRevoke: async (typedData, signature) => {
|
|
257
|
+
return await myCustomRelayer.revoke(typedData, signature);
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
});
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## API Reference
|
|
264
|
+
|
|
265
|
+
### Permissions Controller
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
// Grant permission (gasless)
|
|
269
|
+
await vana.permissions.grant({
|
|
270
|
+
to: Address, // Application address
|
|
271
|
+
operation: string, // Operation type
|
|
272
|
+
parameters: object, // Operation parameters
|
|
273
|
+
expiresAt?: number // Optional expiration timestamp
|
|
274
|
+
}): Promise<Hash>
|
|
275
|
+
|
|
276
|
+
// Revoke permission (gasless)
|
|
277
|
+
await vana.permissions.revoke({
|
|
278
|
+
grantId: string, // Grant ID to revoke
|
|
279
|
+
nonce?: bigint // Optional nonce override
|
|
280
|
+
}): Promise<Hash>
|
|
281
|
+
|
|
282
|
+
// Query user permissions
|
|
283
|
+
await vana.permissions.getUserPermissions({
|
|
284
|
+
user: Address, // User address
|
|
285
|
+
subgraphUrl?: string // Optional subgraph override
|
|
286
|
+
}): Promise<GrantedPermission[]>
|
|
287
|
+
|
|
288
|
+
// Trust a server
|
|
289
|
+
await vana.permissions.trustServer({
|
|
290
|
+
serverAddress: Address, // Server's address
|
|
291
|
+
serverUrl: string // Server's URL
|
|
292
|
+
}): Promise<Hash>
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Data Controller
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
// Get user files
|
|
299
|
+
await vana.data.getUserFiles({
|
|
300
|
+
user: Address, // File owner address
|
|
301
|
+
subgraphUrl?: string // Optional subgraph override
|
|
302
|
+
}): Promise<UserFile[]>
|
|
303
|
+
|
|
304
|
+
// Upload encrypted file
|
|
305
|
+
await vana.data.uploadEncryptedFile({
|
|
306
|
+
data: Blob, // Encrypted file data
|
|
307
|
+
schemaId?: number, // Optional schema ID
|
|
308
|
+
filename?: string // Optional filename
|
|
309
|
+
}): Promise<UploadEncryptedFileResult>
|
|
310
|
+
|
|
311
|
+
// Validate data schema
|
|
312
|
+
vana.data.validateDataSchema(
|
|
313
|
+
schema: unknown // Schema to validate
|
|
314
|
+
): asserts schema is DataSchema
|
|
315
|
+
|
|
316
|
+
// Validate data against schema
|
|
317
|
+
vana.data.validateDataAgainstSchema(
|
|
318
|
+
data: unknown, // Data to validate
|
|
319
|
+
schema: DataSchema // Data schema
|
|
320
|
+
): void
|
|
321
|
+
|
|
322
|
+
// Fetch and validate remote schema
|
|
323
|
+
await vana.data.fetchAndValidateSchema(
|
|
324
|
+
url: string // Schema URL
|
|
325
|
+
): Promise<DataSchema>
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Server Controller
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
// Process data with trusted server
|
|
332
|
+
await vana.server.processWithTrustedServer({
|
|
333
|
+
serverUrl: string, // Trusted server URL
|
|
334
|
+
operation: string, // Operation to perform
|
|
335
|
+
parameters: object // Operation parameters
|
|
336
|
+
}): Promise<any>
|
|
337
|
+
|
|
338
|
+
// Check server trust status
|
|
339
|
+
await vana.server.isServerTrusted({
|
|
340
|
+
user: Address, // User address
|
|
341
|
+
serverAddress: Address // Server address
|
|
342
|
+
}): Promise<boolean>
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Protocol Controller
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
// Get contract information
|
|
349
|
+
vana.protocol.getContract(
|
|
350
|
+
contractName: VanaContract // Contract name
|
|
351
|
+
): ContractInfo
|
|
352
|
+
|
|
353
|
+
// List available contracts
|
|
354
|
+
vana.protocol.getAvailableContracts(): VanaContract[]
|
|
355
|
+
|
|
356
|
+
// Get contract addresses for chain
|
|
357
|
+
vana.protocol.getChainContracts(
|
|
358
|
+
chainId: number // Chain ID
|
|
359
|
+
): Record<VanaContract, Address>
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
## Storage Integration
|
|
363
|
+
|
|
364
|
+
The SDK includes a powerful storage abstraction supporting multiple providers:
|
|
365
|
+
|
|
366
|
+
### IPFS Storage
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
import { StorageManager, PinataStorage } from "vana-sdk";
|
|
370
|
+
|
|
371
|
+
const storageManager = new StorageManager();
|
|
372
|
+
|
|
373
|
+
// Configure Pinata IPFS
|
|
374
|
+
const pinataStorage = new PinataStorage({
|
|
375
|
+
apiKey: process.env.PINATA_API_KEY,
|
|
376
|
+
secretKey: process.env.PINATA_SECRET_KEY,
|
|
377
|
+
gatewayUrl: "https://gateway.pinata.cloud/ipfs",
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
storageManager.register("ipfs", pinataStorage, true); // Default provider
|
|
381
|
+
|
|
382
|
+
// Upload file
|
|
383
|
+
const result = await storageManager.upload(encryptedBlob, "encrypted-data.bin");
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Google Drive Storage
|
|
387
|
+
|
|
388
|
+
```typescript
|
|
389
|
+
import { StorageManager, GoogleDriveStorage } from "vana-sdk";
|
|
390
|
+
|
|
391
|
+
const googleDriveStorage = new GoogleDriveStorage({
|
|
392
|
+
accessToken: process.env.GOOGLE_DRIVE_ACCESS_TOKEN,
|
|
393
|
+
refreshToken: process.env.GOOGLE_DRIVE_REFRESH_TOKEN,
|
|
394
|
+
clientId: process.env.GOOGLE_DRIVE_CLIENT_ID,
|
|
395
|
+
clientSecret: process.env.GOOGLE_DRIVE_CLIENT_SECRET,
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
storageManager.register("google-drive", googleDriveStorage);
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
### Custom Storage Provider
|
|
402
|
+
|
|
403
|
+
```typescript
|
|
404
|
+
class CustomStorage implements StorageProvider {
|
|
405
|
+
async upload(file: Blob, filename?: string): Promise<StorageUploadResult> {
|
|
406
|
+
// Custom upload logic
|
|
407
|
+
return { url: "custom://uploaded-file", size: file.size };
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
async download(url: string): Promise<Blob> {
|
|
411
|
+
// Custom download logic
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// ... other required methods
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
storageManager.register("custom", new CustomStorage());
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
## Error Handling
|
|
421
|
+
|
|
422
|
+
The SDK provides comprehensive error handling with specific error types:
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
import {
|
|
426
|
+
RelayerError,
|
|
427
|
+
UserRejectedRequestError,
|
|
428
|
+
SchemaValidationError,
|
|
429
|
+
InvalidConfigurationError,
|
|
430
|
+
NetworkError,
|
|
431
|
+
} from "vana-sdk";
|
|
432
|
+
|
|
433
|
+
try {
|
|
434
|
+
await vana.permissions.grant(params);
|
|
435
|
+
} catch (error) {
|
|
436
|
+
if (error instanceof UserRejectedRequestError) {
|
|
437
|
+
// User rejected the signature request
|
|
438
|
+
console.log("User cancelled transaction");
|
|
439
|
+
} else if (error instanceof RelayerError) {
|
|
440
|
+
// Relayer service error
|
|
441
|
+
console.log(`Relayer error (${error.statusCode}): ${error.message}`);
|
|
442
|
+
} else if (error instanceof SchemaValidationError) {
|
|
443
|
+
// Schema validation failed
|
|
444
|
+
console.log(`Schema error: ${error.message}`);
|
|
445
|
+
} else if (error instanceof NetworkError) {
|
|
446
|
+
// Network connectivity issue
|
|
447
|
+
console.log(`Network error: ${error.message}`);
|
|
448
|
+
} else {
|
|
449
|
+
// Unexpected error
|
|
450
|
+
console.error("Unexpected error:", error);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
## Supported Networks
|
|
456
|
+
|
|
457
|
+
| Network | Chain ID | RPC URL | Explorer |
|
|
458
|
+
| ------------------ | -------- | ----------------------------- | ------------------------------------------------ |
|
|
459
|
+
| **Vana Mainnet** | `1480` | `https://rpc.vana.org` | [vanascan.io](https://vanascan.io) |
|
|
460
|
+
| **Moksha Testnet** | `14800` | `https://rpc.moksha.vana.org` | [moksha.vanascan.io](https://moksha.vanascan.io) |
|
|
461
|
+
|
|
462
|
+
### Adding Networks to Wallet
|
|
463
|
+
|
|
464
|
+
**Moksha Testnet:**
|
|
465
|
+
|
|
466
|
+
```
|
|
467
|
+
Network Name: Vana Moksha Testnet
|
|
468
|
+
RPC URL: https://rpc.moksha.vana.org
|
|
469
|
+
Chain ID: 14800
|
|
470
|
+
Currency Symbol: VANA
|
|
471
|
+
Block Explorer: https://moksha.vanascan.io
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
## Examples
|
|
475
|
+
|
|
476
|
+
### Complete Permission Flow
|
|
477
|
+
|
|
478
|
+
```typescript
|
|
479
|
+
import { Vana, generateEncryptionKey, encryptUserData } from "vana-sdk";
|
|
480
|
+
|
|
481
|
+
async function completePermissionFlow() {
|
|
482
|
+
// 1. Initialize SDK
|
|
483
|
+
const vana = new Vana({ walletClient });
|
|
484
|
+
|
|
485
|
+
// 2. Encrypt user data
|
|
486
|
+
const encryptionKey = await generateEncryptionKey(walletClient);
|
|
487
|
+
const userData = new Blob([JSON.stringify({ data: "sensitive info" })]);
|
|
488
|
+
const encryptedData = await encryptUserData(userData, encryptionKey);
|
|
489
|
+
|
|
490
|
+
// 3. Upload encrypted file
|
|
491
|
+
const uploadResult = await vana.data.uploadEncryptedFile({
|
|
492
|
+
data: encryptedData,
|
|
493
|
+
schemaId: 123,
|
|
494
|
+
filename: "user-data.json",
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
// 4. Grant permission to access the file
|
|
498
|
+
const permissionTx = await vana.permissions.grant({
|
|
499
|
+
to: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36",
|
|
500
|
+
operation: "ai_training",
|
|
501
|
+
parameters: {
|
|
502
|
+
files: [uploadResult.fileId],
|
|
503
|
+
model: "llm-v1",
|
|
504
|
+
maxTokens: 500,
|
|
505
|
+
},
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
console.log("Permission granted:", permissionTx);
|
|
509
|
+
}
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
### Schema Validation Example
|
|
513
|
+
|
|
514
|
+
```typescript
|
|
515
|
+
// Define a data schema
|
|
516
|
+
const instagramSchema = {
|
|
517
|
+
name: "Instagram Export",
|
|
518
|
+
version: "1.0.0",
|
|
519
|
+
description: "User's Instagram profile and posts data",
|
|
520
|
+
dialect: "json",
|
|
521
|
+
schema: {
|
|
522
|
+
type: "object",
|
|
523
|
+
properties: {
|
|
524
|
+
profile: {
|
|
525
|
+
type: "object",
|
|
526
|
+
properties: {
|
|
527
|
+
username: { type: "string" },
|
|
528
|
+
followers: { type: "number" },
|
|
529
|
+
verified: { type: "boolean" },
|
|
530
|
+
},
|
|
531
|
+
required: ["username"],
|
|
532
|
+
},
|
|
533
|
+
posts: {
|
|
534
|
+
type: "array",
|
|
535
|
+
items: {
|
|
536
|
+
type: "object",
|
|
537
|
+
properties: {
|
|
538
|
+
id: { type: "string" },
|
|
539
|
+
likes: { type: "number" },
|
|
540
|
+
caption: { type: "string" },
|
|
541
|
+
},
|
|
542
|
+
},
|
|
543
|
+
},
|
|
544
|
+
},
|
|
545
|
+
required: ["profile"],
|
|
546
|
+
},
|
|
547
|
+
};
|
|
548
|
+
|
|
549
|
+
// Validate the schema
|
|
550
|
+
vana.data.validateDataSchema(instagramSchema);
|
|
551
|
+
|
|
552
|
+
// Validate user data against the schema
|
|
553
|
+
const userData = {
|
|
554
|
+
profile: { username: "alice_smith", followers: 1500, verified: false },
|
|
555
|
+
posts: [{ id: "post_123", likes: 42, caption: "Beautiful sunset! 🌅" }],
|
|
556
|
+
};
|
|
557
|
+
|
|
558
|
+
vana.data.validateDataAgainstSchema(userData, instagramSchema);
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
## Contributing
|
|
562
|
+
|
|
563
|
+
We welcome contributions to the Vana SDK! Please see our [Contributing Guide](../../CONTRIBUTING.md) for details.
|
|
564
|
+
|
|
565
|
+
### Development Setup
|
|
566
|
+
|
|
567
|
+
```bash
|
|
568
|
+
git clone https://github.com/vana-com/vana-sdk.git
|
|
569
|
+
cd vana-sdk
|
|
570
|
+
npm install
|
|
571
|
+
npm run build
|
|
572
|
+
npm test
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
### Running Examples
|
|
576
|
+
|
|
577
|
+
```bash
|
|
578
|
+
cd examples/vana-sdk-demo
|
|
579
|
+
npm install
|
|
580
|
+
npm run dev
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
## Documentation
|
|
584
|
+
|
|
585
|
+
- [📚 API Documentation](https://vana-com.github.io/vana-sdk) - Complete TypeDoc API reference
|
|
586
|
+
- [🚀 Getting Started Guide](https://docs.vana.org/vana-sdk) - Step-by-step setup
|
|
587
|
+
- [🏗️ Architecture Guide](https://docs.vana.org/vana-sdk/architecture) - SDK design and patterns
|
|
588
|
+
- [🔧 Configuration Guide](https://docs.vana.org/vana-sdk/configuration) - All configuration options
|
|
589
|
+
- [🔒 Security Guide](https://docs.vana.org/vana-sdk/security) - Best practices and security
|
|
590
|
+
|
|
591
|
+
## Support
|
|
592
|
+
|
|
593
|
+
- **📖 Documentation**: [API Reference](https://vana-com.github.io/vana-sdk)
|
|
594
|
+
- **💬 Discord**: [Join our community](https://discord.gg/vanabuilders)
|
|
595
|
+
- **🐛 Issues**: [GitHub Issues](https://github.com/vana-com/vana-sdk/issues)
|
|
596
|
+
- **📧 Email**: [support@vana.org](mailto:support@vana.org)
|
|
597
|
+
|
|
598
|
+
## License
|
|
599
|
+
|
|
600
|
+
[ISC License](LICENSE) © Vana Foundation
|