@opendatalabs/vana-sdk 0.1.0-alpha.e64ec83 → 0.1.0-alpha.f05a34e
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/README.md +189 -425
- package/dist/chains.browser.cjs +4 -1
- package/dist/chains.browser.cjs.map +1 -1
- package/dist/chains.browser.d.cts +2 -1
- package/dist/chains.browser.d.ts +2 -1
- package/dist/chains.browser.js +3 -1
- package/dist/chains.browser.js.map +1 -1
- package/dist/chains.cjs +4 -1
- package/dist/chains.cjs.map +1 -1
- package/dist/chains.d.cts +1 -1
- package/dist/chains.d.ts +1 -1
- package/dist/chains.js +3 -1
- package/dist/chains.js.map +1 -1
- package/dist/chains.node.cjs +4 -1
- package/dist/chains.node.cjs.map +1 -1
- package/dist/chains.node.d.cts +1 -1
- package/dist/chains.node.d.ts +1 -1
- package/dist/chains.node.js +3 -1
- package/dist/chains.node.js.map +1 -1
- package/dist/index.browser.d.ts +3883 -2669
- package/dist/index.browser.js +1412 -1094
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.cts +1 -31277
- package/dist/index.node.cjs +1448 -1131
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.d.cts +3885 -2671
- package/dist/index.node.d.ts +3885 -2671
- package/dist/index.node.js +1427 -1110
- package/dist/index.node.js.map +1 -1
- package/dist/platform.browser.js +32 -181
- package/dist/platform.browser.js.map +1 -1
- package/dist/platform.cjs +47 -197
- package/dist/platform.cjs.map +1 -1
- package/dist/platform.js +47 -197
- package/dist/platform.js.map +1 -1
- package/dist/platform.node.cjs +47 -197
- package/dist/platform.node.cjs.map +1 -1
- package/dist/platform.node.js +47 -197
- package/dist/platform.node.js.map +1 -1
- package/package.json +24 -18
package/README.md
CHANGED
|
@@ -1,33 +1,23 @@
|
|
|
1
1
|
# Vana SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> **⚠️ ALPHA SOFTWARE - EXPERIMENTAL USE ONLY**
|
|
4
|
+
>
|
|
5
|
+
> This SDK is in early alpha development and is **NOT SUITABLE FOR PRODUCTION USE**.
|
|
6
|
+
> Features may change without notice, and data loss or unexpected behavior may occur.
|
|
7
|
+
> Use at your own risk and avoid using with mainnet assets or critical operations.
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
A TypeScript SDK for building data-driven applications on the Vana Network. Enable users to grant gasless permissions, manage encrypted data, and interact with privacy-preserving infrastructure.
|
|
10
|
+
|
|
11
|
+
[](https://www.npmjs.com/package/@opendatalabs/vana-sdk)
|
|
6
12
|
[](https://www.typescriptlang.org/)
|
|
7
13
|
[](https://opensource.org/licenses/ISC)
|
|
8
14
|
|
|
9
|
-
[Documentation](https://vana-com.github.io/vana-sdk) • [Examples](#examples) • [
|
|
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
|
|
15
|
+
[API Documentation](https://vana-com.github.io/vana-sdk) • [Examples](#examples) • [Configuration](#configuration)
|
|
19
16
|
|
|
20
17
|
## Installation
|
|
21
18
|
|
|
22
19
|
```bash
|
|
23
|
-
|
|
24
|
-
npm install vana-sdk
|
|
25
|
-
|
|
26
|
-
# yarn
|
|
27
|
-
yarn add vana-sdk
|
|
28
|
-
|
|
29
|
-
# pnpm
|
|
30
|
-
pnpm add vana-sdk
|
|
20
|
+
npm install @opendatalabs/vana-sdk
|
|
31
21
|
```
|
|
32
22
|
|
|
33
23
|
**Peer Dependencies:**
|
|
@@ -38,13 +28,15 @@ npm install viem@^2.31.7
|
|
|
38
28
|
|
|
39
29
|
## Quick Start
|
|
40
30
|
|
|
41
|
-
|
|
31
|
+
The Vana SDK supports both browser and Node.js environments with explicit entry points:
|
|
32
|
+
|
|
33
|
+
### Browser Applications (React, Vue, etc.)
|
|
42
34
|
|
|
43
35
|
```typescript
|
|
44
|
-
|
|
36
|
+
// For browser-based applications (React, Vue, etc.)
|
|
37
|
+
import { Vana, mokshaTestnet } from "@opendatalabs/vana-sdk/browser";
|
|
45
38
|
import { createWalletClient, http } from "viem";
|
|
46
39
|
import { privateKeyToAccount } from "viem/accounts";
|
|
47
|
-
import { mokshaTestnet } from "vana-sdk";
|
|
48
40
|
|
|
49
41
|
// Create wallet client
|
|
50
42
|
const account = privateKeyToAccount("0x...");
|
|
@@ -54,104 +46,132 @@ const walletClient = createWalletClient({
|
|
|
54
46
|
transport: http("https://rpc.moksha.vana.org"),
|
|
55
47
|
});
|
|
56
48
|
|
|
57
|
-
// Initialize
|
|
58
|
-
const vana =
|
|
49
|
+
// Initialize SDK
|
|
50
|
+
const vana = Vana({
|
|
59
51
|
walletClient,
|
|
60
|
-
// Optional: configure gasless relayer
|
|
61
52
|
relayerUrl: "https://relayer.moksha.vana.org",
|
|
62
53
|
});
|
|
63
54
|
```
|
|
64
55
|
|
|
65
|
-
###
|
|
56
|
+
### Server-side Applications (Next.js API routes, Express)
|
|
66
57
|
|
|
67
58
|
```typescript
|
|
68
|
-
//
|
|
59
|
+
// For server-side applications (Next.js API routes, Express)
|
|
60
|
+
import { Vana, mokshaTestnet } from "@opendatalabs/vana-sdk/node";
|
|
61
|
+
import { createWalletClient, http } from "viem";
|
|
62
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
63
|
+
|
|
64
|
+
// Create wallet client
|
|
65
|
+
const account = privateKeyToAccount("0x...");
|
|
66
|
+
const walletClient = createWalletClient({
|
|
67
|
+
account,
|
|
68
|
+
chain: mokshaTestnet,
|
|
69
|
+
transport: http("https://rpc.moksha.vana.org"),
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Initialize SDK
|
|
73
|
+
const vana = Vana({
|
|
74
|
+
walletClient,
|
|
75
|
+
relayerUrl: "https://relayer.moksha.vana.org",
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// Grant gasless permission
|
|
69
79
|
const txHash = await vana.permissions.grant({
|
|
70
|
-
|
|
80
|
+
grantee: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36",
|
|
71
81
|
operation: "llm_inference",
|
|
72
82
|
parameters: {
|
|
73
|
-
prompt: "Analyze my
|
|
83
|
+
prompt: "Analyze my data for insights",
|
|
74
84
|
maxTokens: 1000,
|
|
75
|
-
files: [12, 15, 28], // Specific file IDs
|
|
76
|
-
model: "gpt-4",
|
|
77
85
|
},
|
|
78
|
-
expiresAt: Math.floor(Date.now() / 1000) +
|
|
86
|
+
expiresAt: Math.floor(Date.now() / 1000) + 86400, // 24 hours
|
|
79
87
|
});
|
|
88
|
+
```
|
|
80
89
|
|
|
81
|
-
|
|
90
|
+
## Core Features
|
|
91
|
+
|
|
92
|
+
### Gasless Permissions
|
|
93
|
+
|
|
94
|
+
Users can grant data access permissions without paying gas fees through EIP-712 signatures and relay infrastructure.
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
// Grant permission with custom parameters
|
|
98
|
+
await vana.permissions.grant({
|
|
99
|
+
grantee: applicationAddress,
|
|
100
|
+
operation: "data_analysis",
|
|
101
|
+
parameters: {
|
|
102
|
+
analysisType: "sentiment",
|
|
103
|
+
files: [12, 15, 28],
|
|
104
|
+
model: "gpt-4",
|
|
105
|
+
},
|
|
106
|
+
});
|
|
82
107
|
```
|
|
83
108
|
|
|
84
|
-
###
|
|
109
|
+
### Encrypted Data Management
|
|
110
|
+
|
|
111
|
+
Upload, query, and manage encrypted user data files with built-in schema validation.
|
|
85
112
|
|
|
86
113
|
```typescript
|
|
87
|
-
//
|
|
114
|
+
// Query user files
|
|
88
115
|
const files = await vana.data.getUserFiles({
|
|
89
|
-
|
|
116
|
+
owner: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36",
|
|
90
117
|
});
|
|
91
118
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
119
|
+
// Upload encrypted file
|
|
120
|
+
const result = await vana.data.uploadEncryptedFile({
|
|
121
|
+
data: encryptedBlob,
|
|
122
|
+
schemaId: 123,
|
|
123
|
+
filename: "user-data.json",
|
|
95
124
|
});
|
|
96
125
|
```
|
|
97
126
|
|
|
98
|
-
###
|
|
127
|
+
### Flexible Storage
|
|
128
|
+
|
|
129
|
+
Abstract storage layer supporting IPFS, Google Drive, and custom providers.
|
|
99
130
|
|
|
100
131
|
```typescript
|
|
101
|
-
//
|
|
102
|
-
|
|
132
|
+
// For browser applications
|
|
133
|
+
import { StorageManager, PinataStorage } from "@opendatalabs/vana-sdk/browser";
|
|
134
|
+
// OR for server-side applications
|
|
135
|
+
// import { StorageManager, PinataStorage } from "@opendatalabs/vana-sdk/node";
|
|
103
136
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
137
|
+
const storageManager = new StorageManager();
|
|
138
|
+
storageManager.register(
|
|
139
|
+
"ipfs",
|
|
140
|
+
new PinataStorage({
|
|
141
|
+
apiKey: process.env.PINATA_API_KEY,
|
|
142
|
+
secretKey: process.env.PINATA_SECRET_KEY,
|
|
108
143
|
}),
|
|
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);
|
|
144
|
+
);
|
|
121
145
|
```
|
|
122
146
|
|
|
123
147
|
## Architecture
|
|
124
148
|
|
|
125
|
-
The
|
|
126
|
-
|
|
127
|
-
### Core Controllers
|
|
149
|
+
The SDK provides four main controllers:
|
|
128
150
|
|
|
129
|
-
| Controller
|
|
130
|
-
|
|
|
131
|
-
|
|
|
132
|
-
|
|
|
133
|
-
|
|
|
134
|
-
|
|
|
151
|
+
| Controller | Purpose | Key Methods |
|
|
152
|
+
| ------------- | ------------------------------ | ----------------------------------------------------------------- |
|
|
153
|
+
| `permissions` | Gasless permission management | `grant()`, `revoke()`, `getUserPermissions()` |
|
|
154
|
+
| `data` | File management and validation | `getUserFiles()`, `uploadEncryptedFile()`, `validateDataSchema()` |
|
|
155
|
+
| `server` | Trusted server operations | `trustServer()`, `processWithTrustedServer()` |
|
|
156
|
+
| `protocol` | Contract interaction | `getContract()`, `getAvailableContracts()` |
|
|
135
157
|
|
|
136
|
-
|
|
158
|
+
## Configuration
|
|
137
159
|
|
|
138
160
|
```typescript
|
|
139
|
-
const vana =
|
|
140
|
-
// Required: Wallet client for signing
|
|
161
|
+
const vana = Vana({
|
|
141
162
|
walletClient,
|
|
142
163
|
|
|
143
|
-
//
|
|
144
|
-
relayerUrl: "https://
|
|
164
|
+
// Gasless transaction relay
|
|
165
|
+
relayerUrl: "https://relayer.moksha.vana.org",
|
|
145
166
|
|
|
146
|
-
//
|
|
167
|
+
// Custom relay callbacks
|
|
147
168
|
relayerCallbacks: {
|
|
148
169
|
submitPermissionGrant: async (typedData, signature) => {
|
|
149
|
-
// Custom relay implementation
|
|
150
170
|
return await customRelayer.submit(typedData, signature);
|
|
151
171
|
},
|
|
152
172
|
},
|
|
153
173
|
|
|
154
|
-
//
|
|
174
|
+
// Storage configuration
|
|
155
175
|
storageManager: new StorageManager({
|
|
156
176
|
defaultProvider: "ipfs",
|
|
157
177
|
providers: {
|
|
@@ -159,441 +179,185 @@ const vana = new Vana({
|
|
|
159
179
|
},
|
|
160
180
|
}),
|
|
161
181
|
|
|
162
|
-
//
|
|
182
|
+
// Subgraph for efficient queries
|
|
163
183
|
subgraphUrl: "https://api.thegraph.com/subgraphs/name/vana/moksha",
|
|
164
184
|
});
|
|
165
185
|
```
|
|
166
186
|
|
|
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
187
|
## Error Handling
|
|
421
188
|
|
|
422
|
-
The SDK provides
|
|
189
|
+
The SDK provides specific error types for different failure scenarios:
|
|
423
190
|
|
|
424
191
|
```typescript
|
|
425
192
|
import {
|
|
426
193
|
RelayerError,
|
|
427
194
|
UserRejectedRequestError,
|
|
428
195
|
SchemaValidationError,
|
|
429
|
-
InvalidConfigurationError,
|
|
430
196
|
NetworkError,
|
|
431
|
-
} from "vana-sdk";
|
|
197
|
+
} from "@opendatalabs/vana-sdk/browser";
|
|
198
|
+
// OR for server-side applications
|
|
199
|
+
// } from "@opendatalabs/vana-sdk/node";
|
|
432
200
|
|
|
433
201
|
try {
|
|
434
202
|
await vana.permissions.grant(params);
|
|
435
203
|
} catch (error) {
|
|
436
204
|
if (error instanceof UserRejectedRequestError) {
|
|
437
|
-
// User
|
|
438
|
-
console.log("User cancelled transaction");
|
|
205
|
+
// User cancelled transaction
|
|
439
206
|
} else if (error instanceof RelayerError) {
|
|
440
207
|
// Relayer service error
|
|
441
|
-
console.log(`Relayer error (${error.statusCode}): ${error.message}`);
|
|
442
208
|
} else if (error instanceof SchemaValidationError) {
|
|
443
209
|
// 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
210
|
}
|
|
452
211
|
}
|
|
453
212
|
```
|
|
454
213
|
|
|
455
214
|
## Supported Networks
|
|
456
215
|
|
|
457
|
-
| Network | Chain ID | RPC URL |
|
|
458
|
-
| ------------------ | -------- | ----------------------------- |
|
|
459
|
-
| **Vana Mainnet** | `1480` | `https://rpc.vana.org` |
|
|
460
|
-
| **Moksha Testnet** | `14800` | `https://rpc.moksha.vana.org` |
|
|
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
|
-
```
|
|
216
|
+
| Network | Chain ID | RPC URL |
|
|
217
|
+
| ------------------ | -------- | ----------------------------- |
|
|
218
|
+
| **Vana Mainnet** | `1480` | `https://rpc.vana.org` |
|
|
219
|
+
| **Moksha Testnet** | `14800` | `https://rpc.moksha.vana.org` |
|
|
473
220
|
|
|
474
221
|
## Examples
|
|
475
222
|
|
|
476
223
|
### Complete Permission Flow
|
|
477
224
|
|
|
478
225
|
```typescript
|
|
479
|
-
import {
|
|
226
|
+
import {
|
|
227
|
+
Vana,
|
|
228
|
+
generateEncryptionKey,
|
|
229
|
+
encryptBlobWithSignedKey,
|
|
230
|
+
} from "@opendatalabs/vana-sdk/browser";
|
|
231
|
+
// OR for server-side applications
|
|
232
|
+
// } from "@opendatalabs/vana-sdk/node";
|
|
480
233
|
|
|
481
|
-
async function
|
|
482
|
-
|
|
483
|
-
const vana = new Vana({ walletClient });
|
|
234
|
+
async function grantDataPermission() {
|
|
235
|
+
const vana = Vana({ walletClient });
|
|
484
236
|
|
|
485
|
-
//
|
|
237
|
+
// 1. Encrypt user data
|
|
486
238
|
const encryptionKey = await generateEncryptionKey(walletClient);
|
|
487
239
|
const userData = new Blob([JSON.stringify({ data: "sensitive info" })]);
|
|
488
|
-
const encryptedData = await
|
|
240
|
+
const encryptedData = await encryptBlobWithSignedKey(userData, encryptionKey);
|
|
489
241
|
|
|
490
|
-
//
|
|
242
|
+
// 2. Upload encrypted file
|
|
491
243
|
const uploadResult = await vana.data.uploadEncryptedFile({
|
|
492
244
|
data: encryptedData,
|
|
493
245
|
schemaId: 123,
|
|
494
246
|
filename: "user-data.json",
|
|
495
247
|
});
|
|
496
248
|
|
|
497
|
-
//
|
|
249
|
+
// 3. Grant permission
|
|
498
250
|
const permissionTx = await vana.permissions.grant({
|
|
499
|
-
|
|
251
|
+
grantee: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36",
|
|
500
252
|
operation: "ai_training",
|
|
501
253
|
parameters: {
|
|
502
254
|
files: [uploadResult.fileId],
|
|
503
255
|
model: "llm-v1",
|
|
504
|
-
maxTokens: 500,
|
|
505
256
|
},
|
|
506
257
|
});
|
|
507
258
|
|
|
508
|
-
|
|
259
|
+
return permissionTx;
|
|
509
260
|
}
|
|
510
261
|
```
|
|
511
262
|
|
|
512
|
-
### Schema Validation
|
|
263
|
+
### Schema Validation
|
|
513
264
|
|
|
514
265
|
```typescript
|
|
515
|
-
// Define
|
|
516
|
-
const
|
|
517
|
-
name: "
|
|
266
|
+
// Define data schema
|
|
267
|
+
const schema = {
|
|
268
|
+
name: "Social Media Export",
|
|
518
269
|
version: "1.0.0",
|
|
519
|
-
description: "User's Instagram profile and posts data",
|
|
520
270
|
dialect: "json",
|
|
521
271
|
schema: {
|
|
522
272
|
type: "object",
|
|
523
273
|
properties: {
|
|
524
|
-
|
|
525
|
-
|
|
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
|
-
},
|
|
274
|
+
posts: { type: "array" },
|
|
275
|
+
profile: { type: "object" },
|
|
544
276
|
},
|
|
545
277
|
required: ["profile"],
|
|
546
278
|
},
|
|
547
279
|
};
|
|
548
280
|
|
|
549
|
-
// Validate
|
|
550
|
-
vana.data.validateDataSchema(
|
|
281
|
+
// Validate schema
|
|
282
|
+
vana.data.validateDataSchema(schema);
|
|
551
283
|
|
|
552
|
-
// Validate user data
|
|
284
|
+
// Validate user data
|
|
553
285
|
const userData = {
|
|
554
|
-
profile: { username: "
|
|
555
|
-
posts: [
|
|
286
|
+
profile: { username: "alice" },
|
|
287
|
+
posts: [],
|
|
556
288
|
};
|
|
557
|
-
|
|
558
|
-
vana.data.validateDataAgainstSchema(userData, instagramSchema);
|
|
289
|
+
vana.data.validateDataAgainstSchema(userData, schema);
|
|
559
290
|
```
|
|
560
291
|
|
|
561
|
-
##
|
|
292
|
+
## API Reference
|
|
562
293
|
|
|
563
|
-
|
|
294
|
+
### Permissions
|
|
564
295
|
|
|
565
|
-
|
|
296
|
+
```typescript
|
|
297
|
+
// Grant permission
|
|
298
|
+
await vana.permissions.grant({
|
|
299
|
+
grantee: Address,
|
|
300
|
+
operation: string,
|
|
301
|
+
parameters: object,
|
|
302
|
+
expiresAt?: number
|
|
303
|
+
}): Promise<Hash>
|
|
566
304
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
305
|
+
// Revoke permission
|
|
306
|
+
await vana.permissions.revoke({
|
|
307
|
+
grantId: string
|
|
308
|
+
}): Promise<Hash>
|
|
309
|
+
|
|
310
|
+
// Get user permissions
|
|
311
|
+
await vana.permissions.getUserPermissions({
|
|
312
|
+
owner: Address
|
|
313
|
+
}): Promise<GrantedPermission[]>
|
|
573
314
|
```
|
|
574
315
|
|
|
575
|
-
###
|
|
316
|
+
### Data
|
|
576
317
|
|
|
577
|
-
```
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
318
|
+
```typescript
|
|
319
|
+
// Get user files
|
|
320
|
+
await vana.data.getUserFiles({
|
|
321
|
+
owner: Address
|
|
322
|
+
}): Promise<UserFile[]>
|
|
323
|
+
|
|
324
|
+
// Upload encrypted file
|
|
325
|
+
await vana.data.uploadEncryptedFile({
|
|
326
|
+
data: Blob,
|
|
327
|
+
schemaId?: number,
|
|
328
|
+
filename?: string
|
|
329
|
+
}): Promise<UploadResult>
|
|
330
|
+
|
|
331
|
+
// Validate schema
|
|
332
|
+
vana.data.validateDataSchema(schema: unknown): void
|
|
333
|
+
|
|
334
|
+
// Validate data against schema
|
|
335
|
+
vana.data.validateDataAgainstSchema(data: unknown, schema: DataSchema): void
|
|
581
336
|
```
|
|
582
337
|
|
|
583
338
|
## Documentation
|
|
584
339
|
|
|
585
|
-
- [
|
|
586
|
-
- [
|
|
587
|
-
- [
|
|
588
|
-
- [
|
|
589
|
-
- [
|
|
340
|
+
- [API Documentation](https://vana-com.github.io/vana-sdk) - Complete TypeDoc API reference
|
|
341
|
+
- [Getting Started](https://vana-com.github.io/vana-sdk/getting-started) - Step-by-step setup guide
|
|
342
|
+
- [Architecture](https://vana-com.github.io/vana-sdk/architecture) - SDK design and patterns
|
|
343
|
+
- [Configuration](https://vana-com.github.io/vana-sdk/configuration) - All configuration options
|
|
344
|
+
- [Security](https://vana-com.github.io/vana-sdk/security) - Best practices and security
|
|
590
345
|
|
|
591
346
|
## Support
|
|
592
347
|
|
|
593
|
-
-
|
|
594
|
-
-
|
|
595
|
-
-
|
|
596
|
-
|
|
348
|
+
- **Documentation**: [vana-com.github.io/vana-sdk](https://vana-com.github.io/vana-sdk)
|
|
349
|
+
- **Issues**: [GitHub Issues](https://github.com/vana-com/vana-sdk/issues)
|
|
350
|
+
- **Discord**: [Join our community](https://discord.gg/vanabuilders)
|
|
351
|
+
|
|
352
|
+
## Development
|
|
353
|
+
|
|
354
|
+
```bash
|
|
355
|
+
git clone https://github.com/vana-com/vana-sdk.git
|
|
356
|
+
cd vana-sdk
|
|
357
|
+
npm install
|
|
358
|
+
npm run build
|
|
359
|
+
npm test
|
|
360
|
+
```
|
|
597
361
|
|
|
598
362
|
## License
|
|
599
363
|
|