@opendatalabs/vana-sdk 0.1.0-alpha.e64ec83 → 0.1.0-alpha.ee24d86
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 +211 -436
- package/dist/chains.browser.cjs +5 -2
- 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 +4 -2
- package/dist/chains.browser.js.map +1 -1
- package/dist/chains.cjs +5 -2
- 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 +4 -2
- package/dist/chains.js.map +1 -1
- package/dist/chains.node.cjs +5 -2
- 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 +4 -2
- package/dist/chains.node.js.map +1 -1
- package/dist/index.browser.d.ts +10186 -4394
- package/dist/index.browser.js +5534 -2049
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.cts +1 -31277
- package/dist/index.node.cjs +5618 -2099
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.d.cts +10211 -4391
- package/dist/index.node.d.ts +10211 -4391
- package/dist/index.node.js +5549 -2032
- package/dist/index.node.js.map +1 -1
- package/dist/platform.browser.d.ts +69 -0
- package/dist/platform.browser.js +79 -181
- package/dist/platform.browser.js.map +1 -1
- package/dist/platform.cjs +122 -197
- package/dist/platform.cjs.map +1 -1
- package/dist/platform.js +122 -197
- package/dist/platform.js.map +1 -1
- package/dist/platform.node.cjs +122 -197
- package/dist/platform.node.cjs.map +1 -1
- package/dist/platform.node.d.cts +70 -0
- package/dist/platform.node.d.ts +70 -0
- package/dist/platform.node.js +122 -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,546 +46,329 @@ 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
|
-
//
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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);
|
|
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
|
|
139
|
-
const vana = new Vana({
|
|
140
|
-
// Required: Wallet client for signing
|
|
72
|
+
// Initialize SDK
|
|
73
|
+
const vana = Vana({
|
|
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
|
+
grantee: "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
|
-
|
|
176
|
-
|
|
97
|
+
// Grant permission with custom parameters
|
|
98
|
+
await vana.permissions.grant({
|
|
99
|
+
grantee: 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
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
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);
|
|
119
|
+
// Upload encrypted file with decryption permissions
|
|
120
|
+
const result = await vana.data.upload({
|
|
121
|
+
content: "Sensitive user data",
|
|
122
|
+
filename: "user-data.json",
|
|
123
|
+
schemaId: 123,
|
|
124
|
+
permissions: [
|
|
125
|
+
{
|
|
126
|
+
account: "0xServerAddress...", // Who can decrypt
|
|
127
|
+
publicKey: "0x04ServerKey...", // Their public key
|
|
258
128
|
},
|
|
259
|
-
|
|
129
|
+
],
|
|
260
130
|
});
|
|
261
131
|
```
|
|
262
132
|
|
|
263
|
-
|
|
133
|
+
### Flexible Storage
|
|
264
134
|
|
|
265
|
-
|
|
135
|
+
Abstract storage layer supporting IPFS, Google Drive, and custom providers.
|
|
266
136
|
|
|
267
137
|
```typescript
|
|
268
|
-
//
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
parameters: object, // Operation parameters
|
|
273
|
-
expiresAt?: number // Optional expiration timestamp
|
|
274
|
-
}): Promise<Hash>
|
|
138
|
+
// For browser applications
|
|
139
|
+
import { StorageManager, PinataStorage } from "@opendatalabs/vana-sdk/browser";
|
|
140
|
+
// OR for server-side applications
|
|
141
|
+
// import { StorageManager, PinataStorage } from "@opendatalabs/vana-sdk/node";
|
|
275
142
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
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>
|
|
143
|
+
const storageManager = new StorageManager();
|
|
144
|
+
storageManager.register(
|
|
145
|
+
"ipfs",
|
|
146
|
+
new PinataStorage({
|
|
147
|
+
apiKey: process.env.PINATA_API_KEY,
|
|
148
|
+
secretKey: process.env.PINATA_SECRET_KEY,
|
|
149
|
+
}),
|
|
150
|
+
);
|
|
343
151
|
```
|
|
344
152
|
|
|
345
|
-
|
|
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
|
-
```
|
|
153
|
+
## Architecture
|
|
361
154
|
|
|
362
|
-
|
|
155
|
+
The SDK provides four main controllers:
|
|
363
156
|
|
|
364
|
-
|
|
157
|
+
| Controller | Purpose | Key Methods |
|
|
158
|
+
| ------------- | ------------------------------ | ----------------------------------------------------------------- |
|
|
159
|
+
| `permissions` | Gasless permission management | `grant()`, `revoke()`, `getUserPermissions()` |
|
|
160
|
+
| `data` | File management and validation | `getUserFiles()`, `uploadEncryptedFile()`, `validateDataSchema()` |
|
|
161
|
+
| `server` | Trusted server operations | `trustServer()`, `processWithTrustedServer()` |
|
|
162
|
+
| `protocol` | Contract interaction | `getContract()`, `getAvailableContracts()` |
|
|
365
163
|
|
|
366
|
-
|
|
164
|
+
## Configuration
|
|
367
165
|
|
|
368
166
|
```typescript
|
|
369
|
-
|
|
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
|
|
167
|
+
const vana = Vana({
|
|
168
|
+
walletClient,
|
|
381
169
|
|
|
382
|
-
//
|
|
383
|
-
|
|
384
|
-
```
|
|
170
|
+
// Gasless transaction relay
|
|
171
|
+
relayerUrl: "https://relayer.moksha.vana.org",
|
|
385
172
|
|
|
386
|
-
|
|
173
|
+
// Custom relay callbacks
|
|
174
|
+
relayerCallbacks: {
|
|
175
|
+
submitPermissionGrant: async (typedData, signature) => {
|
|
176
|
+
return await customRelayer.submit(typedData, signature);
|
|
177
|
+
},
|
|
178
|
+
},
|
|
387
179
|
|
|
388
|
-
|
|
389
|
-
|
|
180
|
+
// Storage configuration
|
|
181
|
+
storageManager: new StorageManager({
|
|
182
|
+
defaultProvider: "ipfs",
|
|
183
|
+
providers: {
|
|
184
|
+
ipfs: new PinataStorage({ apiKey: "...", secretKey: "..." }),
|
|
185
|
+
},
|
|
186
|
+
}),
|
|
390
187
|
|
|
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,
|
|
188
|
+
// Subgraph for efficient queries
|
|
189
|
+
subgraphUrl: "https://api.thegraph.com/subgraphs/name/vana/moksha",
|
|
396
190
|
});
|
|
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
191
|
```
|
|
419
192
|
|
|
420
193
|
## Error Handling
|
|
421
194
|
|
|
422
|
-
The SDK provides
|
|
195
|
+
The SDK provides specific error types for different failure scenarios:
|
|
423
196
|
|
|
424
197
|
```typescript
|
|
425
198
|
import {
|
|
426
199
|
RelayerError,
|
|
427
200
|
UserRejectedRequestError,
|
|
428
201
|
SchemaValidationError,
|
|
429
|
-
InvalidConfigurationError,
|
|
430
202
|
NetworkError,
|
|
431
|
-
} from "vana-sdk";
|
|
203
|
+
} from "@opendatalabs/vana-sdk/browser";
|
|
204
|
+
// OR for server-side applications
|
|
205
|
+
// } from "@opendatalabs/vana-sdk/node";
|
|
432
206
|
|
|
433
207
|
try {
|
|
434
208
|
await vana.permissions.grant(params);
|
|
435
209
|
} catch (error) {
|
|
436
210
|
if (error instanceof UserRejectedRequestError) {
|
|
437
|
-
// User
|
|
438
|
-
console.log("User cancelled transaction");
|
|
211
|
+
// User cancelled transaction
|
|
439
212
|
} else if (error instanceof RelayerError) {
|
|
440
213
|
// Relayer service error
|
|
441
|
-
console.log(`Relayer error (${error.statusCode}): ${error.message}`);
|
|
442
214
|
} else if (error instanceof SchemaValidationError) {
|
|
443
215
|
// 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
216
|
}
|
|
452
217
|
}
|
|
453
218
|
```
|
|
454
219
|
|
|
455
220
|
## Supported Networks
|
|
456
221
|
|
|
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
|
-
```
|
|
222
|
+
| Network | Chain ID | RPC URL |
|
|
223
|
+
| ------------------ | -------- | ----------------------------- |
|
|
224
|
+
| **Vana Mainnet** | `1480` | `https://rpc.vana.org` |
|
|
225
|
+
| **Moksha Testnet** | `14800` | `https://rpc.moksha.vana.org` |
|
|
473
226
|
|
|
474
227
|
## Examples
|
|
475
228
|
|
|
476
|
-
### Complete
|
|
229
|
+
### Complete Data Sharing Flow
|
|
477
230
|
|
|
478
231
|
```typescript
|
|
479
|
-
import { Vana
|
|
232
|
+
import { Vana } from "@opendatalabs/vana-sdk/browser";
|
|
233
|
+
// OR for server-side applications
|
|
234
|
+
// } from "@opendatalabs/vana-sdk/node";
|
|
480
235
|
|
|
481
|
-
async function
|
|
482
|
-
|
|
483
|
-
const vana = new Vana({ walletClient });
|
|
236
|
+
async function shareDataWithServer() {
|
|
237
|
+
const vana = Vana({ walletClient });
|
|
484
238
|
|
|
485
|
-
//
|
|
486
|
-
const
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
// 3. Upload encrypted file
|
|
491
|
-
const uploadResult = await vana.data.uploadEncryptedFile({
|
|
492
|
-
data: encryptedData,
|
|
239
|
+
// Step 1: Upload encrypted file with decryption permissions
|
|
240
|
+
const uploadResult = await vana.data.upload({
|
|
241
|
+
content: { data: "sensitive medical records" },
|
|
242
|
+
filename: "health-data.json",
|
|
493
243
|
schemaId: 123,
|
|
494
|
-
|
|
244
|
+
permissions: [
|
|
245
|
+
{
|
|
246
|
+
// Grant decryption access to the AI server
|
|
247
|
+
account: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36",
|
|
248
|
+
publicKey: "0x04abc...", // Server's public key for encryption
|
|
249
|
+
},
|
|
250
|
+
],
|
|
495
251
|
});
|
|
496
252
|
|
|
497
|
-
//
|
|
498
|
-
const
|
|
499
|
-
|
|
500
|
-
|
|
253
|
+
// Step 2: Grant operation permissions for what the server can do
|
|
254
|
+
const permissionResult = await vana.permissions.grant({
|
|
255
|
+
grantee: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36",
|
|
256
|
+
fileIds: [BigInt(uploadResult.fileId)],
|
|
257
|
+
operation: "medical_analysis",
|
|
501
258
|
parameters: {
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
maxTokens: 500,
|
|
259
|
+
model: "medical-ai-v2",
|
|
260
|
+
analysisType: "comprehensive",
|
|
505
261
|
},
|
|
506
262
|
});
|
|
507
263
|
|
|
508
|
-
|
|
264
|
+
return { uploadResult, permissionResult };
|
|
509
265
|
}
|
|
510
266
|
```
|
|
511
267
|
|
|
512
|
-
### Schema Validation
|
|
268
|
+
### Schema Validation
|
|
513
269
|
|
|
514
270
|
```typescript
|
|
515
|
-
// Define
|
|
516
|
-
const
|
|
517
|
-
name: "
|
|
271
|
+
// Define data schema
|
|
272
|
+
const schema = {
|
|
273
|
+
name: "Social Media Export",
|
|
518
274
|
version: "1.0.0",
|
|
519
|
-
description: "User's Instagram profile and posts data",
|
|
520
275
|
dialect: "json",
|
|
521
276
|
schema: {
|
|
522
277
|
type: "object",
|
|
523
278
|
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
|
-
},
|
|
279
|
+
posts: { type: "array" },
|
|
280
|
+
profile: { type: "object" },
|
|
544
281
|
},
|
|
545
282
|
required: ["profile"],
|
|
546
283
|
},
|
|
547
284
|
};
|
|
548
285
|
|
|
549
|
-
// Validate
|
|
550
|
-
vana.data.validateDataSchema(
|
|
286
|
+
// Validate schema
|
|
287
|
+
vana.data.validateDataSchema(schema);
|
|
551
288
|
|
|
552
|
-
// Validate user data
|
|
289
|
+
// Validate user data
|
|
553
290
|
const userData = {
|
|
554
|
-
profile: { username: "
|
|
555
|
-
posts: [
|
|
291
|
+
profile: { username: "alice" },
|
|
292
|
+
posts: [],
|
|
556
293
|
};
|
|
557
|
-
|
|
558
|
-
vana.data.validateDataAgainstSchema(userData, instagramSchema);
|
|
294
|
+
vana.data.validateDataAgainstSchema(userData, schema);
|
|
559
295
|
```
|
|
560
296
|
|
|
561
|
-
##
|
|
297
|
+
## API Reference
|
|
562
298
|
|
|
563
|
-
|
|
299
|
+
### Permissions
|
|
564
300
|
|
|
565
|
-
|
|
301
|
+
```typescript
|
|
302
|
+
// Grant operation permission
|
|
303
|
+
await vana.permissions.grant({
|
|
304
|
+
grantee: Address,
|
|
305
|
+
fileIds: bigint[],
|
|
306
|
+
operation: string,
|
|
307
|
+
parameters: object,
|
|
308
|
+
expiresAt?: number
|
|
309
|
+
}): Promise<PermissionGrantResult>
|
|
310
|
+
|
|
311
|
+
// Revoke permission
|
|
312
|
+
await vana.permissions.revoke({
|
|
313
|
+
grantId: string
|
|
314
|
+
}): Promise<Hash>
|
|
566
315
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
npm run build
|
|
572
|
-
npm test
|
|
316
|
+
// Get user permissions
|
|
317
|
+
await vana.permissions.getUserPermissions({
|
|
318
|
+
owner: Address
|
|
319
|
+
}): Promise<GrantedPermission[]>
|
|
573
320
|
```
|
|
574
321
|
|
|
575
|
-
###
|
|
322
|
+
### Data
|
|
576
323
|
|
|
577
|
-
```
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
324
|
+
```typescript
|
|
325
|
+
// Get user files
|
|
326
|
+
await vana.data.getUserFiles({
|
|
327
|
+
owner: Address
|
|
328
|
+
}): Promise<UserFile[]>
|
|
329
|
+
|
|
330
|
+
// Upload data with automatic encryption
|
|
331
|
+
await vana.data.upload({
|
|
332
|
+
content: string | Blob | Buffer,
|
|
333
|
+
filename?: string,
|
|
334
|
+
schemaId?: number,
|
|
335
|
+
permissions?: Array<{
|
|
336
|
+
account: Address, // Who can decrypt
|
|
337
|
+
publicKey: string // Their public key
|
|
338
|
+
}>,
|
|
339
|
+
encrypt?: boolean // Default: true
|
|
340
|
+
}): Promise<UploadResult>
|
|
341
|
+
|
|
342
|
+
// Validate schema
|
|
343
|
+
vana.data.validateDataSchema(schema: unknown): void
|
|
344
|
+
|
|
345
|
+
// Validate data against schema
|
|
346
|
+
vana.data.validateDataAgainstSchema(data: unknown, schema: DataSchema): void
|
|
581
347
|
```
|
|
582
348
|
|
|
583
349
|
## Documentation
|
|
584
350
|
|
|
585
|
-
- [
|
|
586
|
-
- [
|
|
587
|
-
- [
|
|
588
|
-
- [
|
|
589
|
-
- [
|
|
351
|
+
- [API Documentation](https://vana-com.github.io/vana-sdk) - Complete TypeDoc API reference
|
|
352
|
+
- [Getting Started](https://vana-com.github.io/vana-sdk/getting-started) - Step-by-step setup guide
|
|
353
|
+
- [Architecture](https://vana-com.github.io/vana-sdk/architecture) - SDK design and patterns
|
|
354
|
+
- [Configuration](https://vana-com.github.io/vana-sdk/configuration) - All configuration options
|
|
355
|
+
- [Security](https://vana-com.github.io/vana-sdk/security) - Best practices and security
|
|
590
356
|
|
|
591
357
|
## Support
|
|
592
358
|
|
|
593
|
-
-
|
|
594
|
-
-
|
|
595
|
-
-
|
|
596
|
-
|
|
359
|
+
- **Documentation**: [vana-com.github.io/vana-sdk](https://vana-com.github.io/vana-sdk)
|
|
360
|
+
- **Issues**: [GitHub Issues](https://github.com/vana-com/vana-sdk/issues)
|
|
361
|
+
- **Discord**: [Join our community](https://discord.gg/vanabuilders)
|
|
362
|
+
|
|
363
|
+
## Development
|
|
364
|
+
|
|
365
|
+
```bash
|
|
366
|
+
git clone https://github.com/vana-com/vana-sdk.git
|
|
367
|
+
cd vana-sdk
|
|
368
|
+
npm install
|
|
369
|
+
npm run build
|
|
370
|
+
npm test
|
|
371
|
+
```
|
|
597
372
|
|
|
598
373
|
## License
|
|
599
374
|
|