@opendatalabs/vana-sdk 0.1.0-alpha.5e925dc → 0.1.0-alpha.793d5ba
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 +184 -420
- package/dist/chains.browser.cjs +96 -0
- package/dist/chains.browser.cjs.map +1 -0
- package/dist/chains.browser.d.cts +53 -0
- package/dist/chains.browser.d.ts +53 -0
- package/dist/chains.browser.js +65 -0
- package/dist/chains.browser.js.map +1 -0
- package/dist/chains.cjs +96 -0
- package/dist/chains.cjs.map +1 -0
- package/dist/chains.d.cts +2 -0
- package/dist/chains.d.ts +2 -0
- package/dist/chains.js +65 -0
- package/dist/chains.js.map +1 -0
- package/dist/chains.node.cjs +96 -0
- package/dist/chains.node.cjs.map +1 -0
- package/dist/chains.node.d.cts +2 -0
- package/dist/chains.node.d.ts +2 -0
- package/dist/chains.node.js +65 -0
- package/dist/chains.node.js.map +1 -0
- package/dist/index.browser.d.ts +3438 -2760
- package/dist/index.browser.js +1164 -1005
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.cts +1 -31191
- package/dist/index.node.cjs +1277 -700
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.d.cts +3463 -2745
- package/dist/index.node.d.ts +3463 -2745
- package/dist/index.node.js +1251 -684
- package/dist/index.node.js.map +1 -1
- package/dist/platform.browser.d.ts +224 -0
- package/dist/platform.browser.js +374 -0
- package/dist/platform.browser.js.map +1 -0
- package/dist/platform.cjs +715 -0
- package/dist/platform.cjs.map +1 -0
- package/dist/platform.d.cts +1 -0
- package/dist/platform.d.ts +1 -0
- package/dist/platform.js +678 -0
- package/dist/platform.js.map +1 -0
- package/dist/platform.node.cjs +715 -0
- package/dist/platform.node.cjs.map +1 -0
- package/dist/platform.node.d.cts +264 -0
- package/dist/platform.node.d.ts +264 -0
- package/dist/platform.node.js +678 -0
- package/dist/platform.node.js.map +1 -0
- package/package.json +44 -12
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,546 +46,318 @@ const walletClient = createWalletClient({
|
|
|
54
46
|
transport: http("https://rpc.moksha.vana.org"),
|
|
55
47
|
});
|
|
56
48
|
|
|
57
|
-
// Initialize
|
|
49
|
+
// Initialize SDK
|
|
58
50
|
const vana = new Vana({
|
|
59
51
|
walletClient,
|
|
60
|
-
// Optional: configure gasless relayer
|
|
61
52
|
relayerUrl: "https://relayer.moksha.vana.org",
|
|
62
53
|
});
|
|
63
54
|
```
|
|
64
55
|
|
|
65
|
-
###
|
|
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
|
|
56
|
+
### Server-side Applications (Next.js API routes, Express)
|
|
99
57
|
|
|
100
58
|
```typescript
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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);
|
|
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";
|
|
112
63
|
|
|
113
|
-
//
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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"),
|
|
118
70
|
});
|
|
119
71
|
|
|
120
|
-
|
|
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
|
|
72
|
+
// Initialize SDK
|
|
139
73
|
const vana = new Vana({
|
|
140
|
-
// Required: Wallet client for signing
|
|
141
74
|
walletClient,
|
|
75
|
+
relayerUrl: "https://relayer.moksha.vana.org",
|
|
76
|
+
});
|
|
142
77
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
return await customRelayer.submit(typedData, signature);
|
|
151
|
-
},
|
|
78
|
+
// Grant gasless permission
|
|
79
|
+
const txHash = await vana.permissions.grant({
|
|
80
|
+
to: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36",
|
|
81
|
+
operation: "llm_inference",
|
|
82
|
+
parameters: {
|
|
83
|
+
prompt: "Analyze my data for insights",
|
|
84
|
+
maxTokens: 1000,
|
|
152
85
|
},
|
|
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",
|
|
86
|
+
expiresAt: Math.floor(Date.now() / 1000) + 86400, // 24 hours
|
|
164
87
|
});
|
|
165
88
|
```
|
|
166
89
|
|
|
167
|
-
## Core
|
|
90
|
+
## Core Features
|
|
168
91
|
|
|
169
92
|
### Gasless Permissions
|
|
170
93
|
|
|
171
|
-
|
|
94
|
+
Users can grant data access permissions without paying gas fees through EIP-712 signatures and relay infrastructure.
|
|
172
95
|
|
|
173
96
|
```typescript
|
|
174
|
-
//
|
|
175
|
-
|
|
97
|
+
// Grant permission with custom parameters
|
|
98
|
+
await vana.permissions.grant({
|
|
176
99
|
to: applicationAddress,
|
|
177
100
|
operation: "data_analysis",
|
|
178
101
|
parameters: {
|
|
179
|
-
// Structured parameters for the operation
|
|
180
102
|
analysisType: "sentiment",
|
|
181
|
-
|
|
182
|
-
|
|
103
|
+
files: [12, 15, 28],
|
|
104
|
+
model: "gpt-4",
|
|
183
105
|
},
|
|
184
106
|
});
|
|
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
107
|
```
|
|
193
108
|
|
|
194
|
-
### Data
|
|
109
|
+
### Encrypted Data Management
|
|
195
110
|
|
|
196
|
-
|
|
111
|
+
Upload, query, and manage encrypted user data files with built-in schema validation.
|
|
197
112
|
|
|
198
113
|
```typescript
|
|
199
|
-
//
|
|
114
|
+
// Query user files
|
|
200
115
|
const files = await vana.data.getUserFiles({
|
|
201
|
-
|
|
202
|
-
// Optional: override subgraph URL
|
|
203
|
-
subgraphUrl: "https://custom-subgraph.com/graphql",
|
|
116
|
+
owner: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36",
|
|
204
117
|
});
|
|
205
118
|
|
|
206
|
-
//
|
|
207
|
-
|
|
208
|
-
|
|
119
|
+
// Upload encrypted file
|
|
120
|
+
const result = await vana.data.uploadEncryptedFile({
|
|
121
|
+
data: encryptedBlob,
|
|
122
|
+
schemaId: 123,
|
|
123
|
+
filename: "user-data.json",
|
|
124
|
+
});
|
|
209
125
|
```
|
|
210
126
|
|
|
211
|
-
###
|
|
127
|
+
### Flexible Storage
|
|
212
128
|
|
|
213
|
-
|
|
129
|
+
Abstract storage layer supporting IPFS, Google Drive, and custom providers.
|
|
214
130
|
|
|
215
131
|
```typescript
|
|
216
|
-
//
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
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);
|
|
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";
|
|
231
136
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
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,
|
|
143
|
+
}),
|
|
144
|
+
);
|
|
235
145
|
```
|
|
236
146
|
|
|
237
|
-
|
|
147
|
+
## Architecture
|
|
148
|
+
|
|
149
|
+
The SDK provides four main controllers:
|
|
238
150
|
|
|
239
|
-
|
|
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()` |
|
|
157
|
+
|
|
158
|
+
## Configuration
|
|
240
159
|
|
|
241
160
|
```typescript
|
|
242
161
|
const vana = new Vana({
|
|
243
162
|
walletClient,
|
|
163
|
+
|
|
164
|
+
// Gasless transaction relay
|
|
165
|
+
relayerUrl: "https://relayer.moksha.vana.org",
|
|
166
|
+
|
|
167
|
+
// Custom relay callbacks
|
|
244
168
|
relayerCallbacks: {
|
|
245
|
-
// Custom permission grant relaying
|
|
246
169
|
submitPermissionGrant: async (typedData, signature) => {
|
|
247
|
-
|
|
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);
|
|
170
|
+
return await customRelayer.submit(typedData, signature);
|
|
258
171
|
},
|
|
259
172
|
},
|
|
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
173
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
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";
|
|
174
|
+
// Storage configuration
|
|
175
|
+
storageManager: new StorageManager({
|
|
176
|
+
defaultProvider: "ipfs",
|
|
177
|
+
providers: {
|
|
178
|
+
ipfs: new PinataStorage({ apiKey: "...", secretKey: "..." }),
|
|
179
|
+
},
|
|
180
|
+
}),
|
|
390
181
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
refreshToken: process.env.GOOGLE_DRIVE_REFRESH_TOKEN,
|
|
394
|
-
clientId: process.env.GOOGLE_DRIVE_CLIENT_ID,
|
|
395
|
-
clientSecret: process.env.GOOGLE_DRIVE_CLIENT_SECRET,
|
|
182
|
+
// Subgraph for efficient queries
|
|
183
|
+
subgraphUrl: "https://api.thegraph.com/subgraphs/name/vana/moksha",
|
|
396
184
|
});
|
|
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
185
|
```
|
|
419
186
|
|
|
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 {
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
226
|
+
import {
|
|
227
|
+
Vana,
|
|
228
|
+
generateEncryptionKey,
|
|
229
|
+
encryptUserData,
|
|
230
|
+
} from "@opendatalabs/vana-sdk/browser";
|
|
231
|
+
// OR for server-side applications
|
|
232
|
+
// } from "@opendatalabs/vana-sdk/node";
|
|
233
|
+
|
|
234
|
+
async function grantDataPermission() {
|
|
483
235
|
const vana = new 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
240
|
const encryptedData = await encryptUserData(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
|
to: "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
|
+
to: 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
|
|