@opendatalabs/vana-sdk 0.1.0-alpha.a145c3c → 0.1.0-alpha.aa3959e
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 +43 -32
- package/dist/browser-DY8XDblx.d.ts +241 -0
- package/dist/browser.d.ts +1 -0
- package/dist/browser.js +309 -0
- package/dist/browser.js.map +1 -0
- package/dist/chains.browser.cjs +2 -2
- package/dist/chains.browser.cjs.map +1 -1
- package/dist/chains.browser.js +2 -2
- package/dist/chains.browser.js.map +1 -1
- package/dist/chains.cjs +2 -2
- package/dist/chains.cjs.map +1 -1
- package/dist/chains.js +2 -2
- package/dist/chains.js.map +1 -1
- package/dist/chains.node.cjs +2 -2
- package/dist/chains.node.cjs.map +1 -1
- package/dist/chains.node.js +2 -2
- package/dist/chains.node.js.map +1 -1
- package/dist/index.browser.d.ts +8734 -5080
- package/dist/index.browser.js +17629 -13494
- package/dist/index.browser.js.map +1 -1
- package/dist/index.node.cjs +17709 -13535
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.d.cts +8741 -5082
- package/dist/index.node.d.ts +8741 -5082
- package/dist/index.node.js +17685 -13513
- package/dist/index.node.js.map +1 -1
- package/dist/node-D9-F9uEP.d.cts +238 -0
- package/dist/node-D9-F9uEP.d.ts +238 -0
- package/dist/node.cjs +348 -0
- package/dist/node.cjs.map +1 -0
- package/dist/node.d.cts +1 -0
- package/dist/node.d.ts +1 -0
- package/dist/node.js +311 -0
- package/dist/node.js.map +1 -0
- package/dist/platform.browser.d.ts +3 -202
- package/dist/platform.browser.js +78 -8
- package/dist/platform.browser.js.map +1 -1
- package/dist/platform.cjs +147 -62
- package/dist/platform.cjs.map +1 -1
- package/dist/platform.d.cts +2 -1
- package/dist/platform.d.ts +2 -1
- package/dist/platform.js +147 -62
- package/dist/platform.js.map +1 -1
- package/dist/platform.node.cjs +147 -62
- package/dist/platform.node.cjs.map +1 -1
- package/dist/platform.node.d.cts +8 -202
- package/dist/platform.node.d.ts +8 -202
- package/dist/platform.node.js +147 -62
- package/dist/platform.node.js.map +1 -1
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -116,11 +116,17 @@ const files = await vana.data.getUserFiles({
|
|
|
116
116
|
owner: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36",
|
|
117
117
|
});
|
|
118
118
|
|
|
119
|
-
// Upload encrypted file
|
|
120
|
-
const result = await vana.data.
|
|
121
|
-
|
|
122
|
-
schemaId: 123,
|
|
119
|
+
// Upload encrypted file with decryption permissions
|
|
120
|
+
const result = await vana.data.upload({
|
|
121
|
+
content: "Sensitive user data",
|
|
123
122
|
filename: "user-data.json",
|
|
123
|
+
schemaId: 123,
|
|
124
|
+
permissions: [
|
|
125
|
+
{
|
|
126
|
+
account: "0xServerAddress...", // Who can decrypt
|
|
127
|
+
publicKey: "0x04ServerKey...", // Their public key
|
|
128
|
+
},
|
|
129
|
+
],
|
|
124
130
|
});
|
|
125
131
|
```
|
|
126
132
|
|
|
@@ -220,43 +226,42 @@ try {
|
|
|
220
226
|
|
|
221
227
|
## Examples
|
|
222
228
|
|
|
223
|
-
### Complete
|
|
229
|
+
### Complete Data Sharing Flow
|
|
224
230
|
|
|
225
231
|
```typescript
|
|
226
|
-
import {
|
|
227
|
-
Vana,
|
|
228
|
-
generateEncryptionKey,
|
|
229
|
-
encryptBlobWithSignedKey,
|
|
230
|
-
} from "@opendatalabs/vana-sdk/browser";
|
|
232
|
+
import { Vana } from "@opendatalabs/vana-sdk/browser";
|
|
231
233
|
// OR for server-side applications
|
|
232
234
|
// } from "@opendatalabs/vana-sdk/node";
|
|
233
235
|
|
|
234
|
-
async function
|
|
236
|
+
async function shareDataWithServer() {
|
|
235
237
|
const vana = Vana({ walletClient });
|
|
236
238
|
|
|
237
|
-
// 1
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
// 2. Upload encrypted file
|
|
243
|
-
const uploadResult = await vana.data.uploadEncryptedFile({
|
|
244
|
-
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",
|
|
245
243
|
schemaId: 123,
|
|
246
|
-
|
|
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
|
+
],
|
|
247
251
|
});
|
|
248
252
|
|
|
249
|
-
//
|
|
250
|
-
const
|
|
253
|
+
// Step 2: Grant operation permissions for what the server can do
|
|
254
|
+
const permissionResult = await vana.permissions.grant({
|
|
251
255
|
grantee: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36",
|
|
252
|
-
|
|
256
|
+
fileIds: [BigInt(uploadResult.fileId)],
|
|
257
|
+
operation: "medical_analysis",
|
|
253
258
|
parameters: {
|
|
254
|
-
|
|
255
|
-
|
|
259
|
+
model: "medical-ai-v2",
|
|
260
|
+
analysisType: "comprehensive",
|
|
256
261
|
},
|
|
257
262
|
});
|
|
258
263
|
|
|
259
|
-
return
|
|
264
|
+
return { uploadResult, permissionResult };
|
|
260
265
|
}
|
|
261
266
|
```
|
|
262
267
|
|
|
@@ -294,13 +299,14 @@ vana.data.validateDataAgainstSchema(userData, schema);
|
|
|
294
299
|
### Permissions
|
|
295
300
|
|
|
296
301
|
```typescript
|
|
297
|
-
// Grant permission
|
|
302
|
+
// Grant operation permission
|
|
298
303
|
await vana.permissions.grant({
|
|
299
304
|
grantee: Address,
|
|
305
|
+
fileIds: bigint[],
|
|
300
306
|
operation: string,
|
|
301
307
|
parameters: object,
|
|
302
308
|
expiresAt?: number
|
|
303
|
-
}): Promise<
|
|
309
|
+
}): Promise<PermissionGrantResult>
|
|
304
310
|
|
|
305
311
|
// Revoke permission
|
|
306
312
|
await vana.permissions.revoke({
|
|
@@ -321,11 +327,16 @@ await vana.data.getUserFiles({
|
|
|
321
327
|
owner: Address
|
|
322
328
|
}): Promise<UserFile[]>
|
|
323
329
|
|
|
324
|
-
// Upload
|
|
325
|
-
await vana.data.
|
|
326
|
-
|
|
330
|
+
// Upload data with automatic encryption
|
|
331
|
+
await vana.data.upload({
|
|
332
|
+
content: string | Blob | Buffer,
|
|
333
|
+
filename?: string,
|
|
327
334
|
schemaId?: number,
|
|
328
|
-
|
|
335
|
+
permissions?: Array<{
|
|
336
|
+
account: Address, // Who can decrypt
|
|
337
|
+
publicKey: string // Their public key
|
|
338
|
+
}>,
|
|
339
|
+
encrypt?: boolean // Default: true
|
|
329
340
|
}): Promise<UploadResult>
|
|
330
341
|
|
|
331
342
|
// Validate schema
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform Adapter interface for environment-specific implementations
|
|
3
|
+
*
|
|
4
|
+
* This interface abstracts all environment-specific dependencies to ensure
|
|
5
|
+
* the SDK works seamlessly across Node.js and browser/SSR environments.
|
|
6
|
+
*
|
|
7
|
+
* **Implementation Context:**
|
|
8
|
+
* - Node.js: Uses native crypto modules and full OpenPGP support
|
|
9
|
+
* - Browser: Uses Web Crypto API and browser-compatible libraries
|
|
10
|
+
* - SSR: Automatically selects appropriate implementation based on runtime
|
|
11
|
+
*
|
|
12
|
+
* **Usage Notes:**
|
|
13
|
+
* Platform adapters are automatically selected by the SDK. Direct usage is only
|
|
14
|
+
* needed for custom implementations or testing.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Platform type identifier
|
|
18
|
+
*/
|
|
19
|
+
type PlatformType = "node" | "browser";
|
|
20
|
+
/**
|
|
21
|
+
* Encryption operations that require different implementations per platform
|
|
22
|
+
*/
|
|
23
|
+
interface VanaCryptoAdapter {
|
|
24
|
+
/**
|
|
25
|
+
* Encrypt data with a public key using asymmetric cryptography
|
|
26
|
+
*
|
|
27
|
+
* **Usage Context:**
|
|
28
|
+
* - Used internally for file encryption before storage
|
|
29
|
+
* - Public key format: Armored PGP public key string
|
|
30
|
+
* - Returns base64-encoded encrypted data
|
|
31
|
+
*
|
|
32
|
+
* @param data The data to encrypt
|
|
33
|
+
* @param publicKey The public key for encryption
|
|
34
|
+
* @returns Promise resolving to encrypted data
|
|
35
|
+
*/
|
|
36
|
+
encryptWithPublicKey(data: string, publicKey: string): Promise<string>;
|
|
37
|
+
/**
|
|
38
|
+
* Decrypt data with a private key using asymmetric cryptography
|
|
39
|
+
*
|
|
40
|
+
* @param encryptedData The encrypted data
|
|
41
|
+
* @param privateKey The private key for decryption
|
|
42
|
+
* @returns Promise resolving to decrypted data
|
|
43
|
+
*/
|
|
44
|
+
decryptWithPrivateKey(encryptedData: string, privateKey: string): Promise<string>;
|
|
45
|
+
/**
|
|
46
|
+
* Generate a new key pair for asymmetric cryptography
|
|
47
|
+
*
|
|
48
|
+
* @returns Promise resolving to public and private key pair
|
|
49
|
+
*/
|
|
50
|
+
generateKeyPair(): Promise<{
|
|
51
|
+
publicKey: string;
|
|
52
|
+
privateKey: string;
|
|
53
|
+
}>;
|
|
54
|
+
/**
|
|
55
|
+
* Encrypt data with a wallet's public key using ECDH cryptography
|
|
56
|
+
* Uses platform-appropriate ECDH implementation (eccrypto vs eccrypto-js)
|
|
57
|
+
*
|
|
58
|
+
* **Usage Context:**
|
|
59
|
+
* - Used for sharing encryption keys with permission recipients
|
|
60
|
+
* - Public key format: Compressed or uncompressed secp256k1 hex string
|
|
61
|
+
* - Compatible with Ethereum wallet public keys
|
|
62
|
+
*
|
|
63
|
+
* @param data The data to encrypt (string)
|
|
64
|
+
* @param publicKey The wallet's public key (secp256k1)
|
|
65
|
+
* @returns Promise resolving to encrypted data as hex string
|
|
66
|
+
*/
|
|
67
|
+
encryptWithWalletPublicKey(data: string, publicKey: string): Promise<string>;
|
|
68
|
+
/**
|
|
69
|
+
* Decrypt data with a wallet's private key using ECDH cryptography
|
|
70
|
+
* Uses platform-appropriate ECDH implementation (eccrypto vs eccrypto-js)
|
|
71
|
+
*
|
|
72
|
+
* @param encryptedData The encrypted data as hex string
|
|
73
|
+
* @param privateKey The wallet's private key (secp256k1)
|
|
74
|
+
* @returns Promise resolving to decrypted data as string
|
|
75
|
+
*/
|
|
76
|
+
decryptWithWalletPrivateKey(encryptedData: string, privateKey: string): Promise<string>;
|
|
77
|
+
/**
|
|
78
|
+
* Encrypt data with a password using PGP password-based encryption
|
|
79
|
+
* Uses platform-appropriate OpenPGP implementation with consistent format
|
|
80
|
+
*
|
|
81
|
+
* @param data The data to encrypt as Uint8Array
|
|
82
|
+
* @param password The password for encryption (typically wallet signature)
|
|
83
|
+
* @returns Promise resolving to encrypted data as Uint8Array
|
|
84
|
+
*/
|
|
85
|
+
encryptWithPassword(data: Uint8Array, password: string): Promise<Uint8Array>;
|
|
86
|
+
/**
|
|
87
|
+
* Decrypt data with a password using PGP password-based decryption
|
|
88
|
+
* Uses platform-appropriate OpenPGP implementation with consistent format
|
|
89
|
+
*
|
|
90
|
+
* @param encryptedData The encrypted data as Uint8Array
|
|
91
|
+
* @param password The password for decryption (typically wallet signature)
|
|
92
|
+
* @returns Promise resolving to decrypted data as Uint8Array
|
|
93
|
+
*/
|
|
94
|
+
decryptWithPassword(encryptedData: Uint8Array, password: string): Promise<Uint8Array>;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* PGP operations that require different configurations per platform
|
|
98
|
+
*/
|
|
99
|
+
interface VanaPGPAdapter {
|
|
100
|
+
/**
|
|
101
|
+
* Encrypt data using PGP with proper platform configuration
|
|
102
|
+
*
|
|
103
|
+
* @param data The data to encrypt
|
|
104
|
+
* @param publicKey The PGP public key
|
|
105
|
+
* @returns Promise resolving to encrypted data
|
|
106
|
+
*/
|
|
107
|
+
encrypt(data: string, publicKey: string): Promise<string>;
|
|
108
|
+
/**
|
|
109
|
+
* Decrypt data using PGP with proper platform configuration
|
|
110
|
+
*
|
|
111
|
+
* @param encryptedData The encrypted data
|
|
112
|
+
* @param privateKey The PGP private key
|
|
113
|
+
* @returns Promise resolving to decrypted data
|
|
114
|
+
*/
|
|
115
|
+
decrypt(encryptedData: string, privateKey: string): Promise<string>;
|
|
116
|
+
/**
|
|
117
|
+
* Generate a new PGP key pair with platform-appropriate configuration
|
|
118
|
+
*
|
|
119
|
+
* @param options - Key generation options
|
|
120
|
+
* @param options.name - The name for the PGP key
|
|
121
|
+
* @param options.email - The email for the PGP key
|
|
122
|
+
* @param options.passphrase - Optional passphrase to protect the private key
|
|
123
|
+
* @returns Promise resolving to public and private key pair
|
|
124
|
+
*/
|
|
125
|
+
generateKeyPair(options?: {
|
|
126
|
+
name?: string;
|
|
127
|
+
email?: string;
|
|
128
|
+
passphrase?: string;
|
|
129
|
+
}): Promise<{
|
|
130
|
+
publicKey: string;
|
|
131
|
+
privateKey: string;
|
|
132
|
+
}>;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* HTTP operations that need consistent API across platforms
|
|
136
|
+
*/
|
|
137
|
+
interface VanaHttpAdapter {
|
|
138
|
+
/**
|
|
139
|
+
* Perform HTTP request with platform-appropriate fetch implementation
|
|
140
|
+
*
|
|
141
|
+
* @param url The URL to request
|
|
142
|
+
* @param options Request options
|
|
143
|
+
* @returns Promise resolving to response
|
|
144
|
+
*/
|
|
145
|
+
fetch(url: string, options?: RequestInit): Promise<Response>;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Simple cache operations that work across platforms
|
|
149
|
+
*/
|
|
150
|
+
interface VanaCacheAdapter {
|
|
151
|
+
/**
|
|
152
|
+
* Get a value from the cache
|
|
153
|
+
*
|
|
154
|
+
* @param key The cache key
|
|
155
|
+
* @returns The cached value or null if not found/expired
|
|
156
|
+
*/
|
|
157
|
+
get(key: string): string | null;
|
|
158
|
+
/**
|
|
159
|
+
* Set a value in the cache
|
|
160
|
+
*
|
|
161
|
+
* @param key The cache key
|
|
162
|
+
* @param value The value to cache
|
|
163
|
+
*/
|
|
164
|
+
set(key: string, value: string): void;
|
|
165
|
+
/**
|
|
166
|
+
* Delete a value from the cache
|
|
167
|
+
*
|
|
168
|
+
* @param key The cache key
|
|
169
|
+
*/
|
|
170
|
+
delete(key: string): void;
|
|
171
|
+
/**
|
|
172
|
+
* Clear all values from the cache
|
|
173
|
+
*/
|
|
174
|
+
clear(): void;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Main platform adapter interface that combines all platform-specific functionality
|
|
178
|
+
*
|
|
179
|
+
* **Implementation Guidelines:**
|
|
180
|
+
* 1. All methods must maintain consistent behavior across platforms
|
|
181
|
+
* 2. Error types and messages should be unified
|
|
182
|
+
* 3. Data formats (encoding, serialization) must be identical
|
|
183
|
+
* 4. Performance characteristics can vary but API must be consistent
|
|
184
|
+
*
|
|
185
|
+
* **Custom Implementation Example:**
|
|
186
|
+
* ```typescript
|
|
187
|
+
* class CustomPlatformAdapter implements VanaPlatformAdapter {
|
|
188
|
+
* crypto = new CustomCryptoAdapter();
|
|
189
|
+
* pgp = new CustomPGPAdapter();
|
|
190
|
+
* http = new CustomHttpAdapter();
|
|
191
|
+
* platform = 'browser' as const;
|
|
192
|
+
* }
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
195
|
+
interface VanaPlatformAdapter {
|
|
196
|
+
/**
|
|
197
|
+
* Crypto operations adapter
|
|
198
|
+
*/
|
|
199
|
+
crypto: VanaCryptoAdapter;
|
|
200
|
+
/**
|
|
201
|
+
* PGP operations adapter
|
|
202
|
+
*/
|
|
203
|
+
pgp: VanaPGPAdapter;
|
|
204
|
+
/**
|
|
205
|
+
* HTTP operations adapter
|
|
206
|
+
*/
|
|
207
|
+
http: VanaHttpAdapter;
|
|
208
|
+
/**
|
|
209
|
+
* Cache operations adapter
|
|
210
|
+
*/
|
|
211
|
+
cache: VanaCacheAdapter;
|
|
212
|
+
/**
|
|
213
|
+
* Platform identifier for debugging/telemetry
|
|
214
|
+
*/
|
|
215
|
+
readonly platform: PlatformType;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Browser implementation of the Vana Platform Adapter
|
|
220
|
+
*
|
|
221
|
+
* This implementation uses browser-compatible libraries and configurations
|
|
222
|
+
* to provide crypto, PGP, and HTTP functionality without Node.js dependencies.
|
|
223
|
+
*
|
|
224
|
+
* WARNING: Dependencies that access globals during init
|
|
225
|
+
* MUST be dynamically imported to support Turbopack.
|
|
226
|
+
* See: https://github.com/vercel/next.js/issues/82632
|
|
227
|
+
*/
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Complete browser platform adapter implementation
|
|
231
|
+
*/
|
|
232
|
+
declare class BrowserPlatformAdapter implements VanaPlatformAdapter {
|
|
233
|
+
crypto: VanaCryptoAdapter;
|
|
234
|
+
pgp: VanaPGPAdapter;
|
|
235
|
+
http: VanaHttpAdapter;
|
|
236
|
+
cache: VanaCacheAdapter;
|
|
237
|
+
platform: "browser";
|
|
238
|
+
constructor();
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export { BrowserPlatformAdapter as B, type PlatformType as P, type VanaPlatformAdapter as V };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { B as BrowserPlatformAdapter } from './browser-DY8XDblx.js';
|
package/dist/browser.js
ADDED
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
|
|
5
|
+
// src/platform/shared/crypto-utils.ts
|
|
6
|
+
function processWalletPublicKey(publicKey) {
|
|
7
|
+
const publicKeyHex = publicKey.startsWith("0x") ? publicKey.slice(2) : publicKey;
|
|
8
|
+
const publicKeyBytes = Buffer.from(publicKeyHex, "hex");
|
|
9
|
+
return publicKeyBytes.length === 64 ? Buffer.concat([Buffer.from([4]), publicKeyBytes]) : publicKeyBytes;
|
|
10
|
+
}
|
|
11
|
+
function processWalletPrivateKey(privateKey) {
|
|
12
|
+
const privateKeyHex = privateKey.startsWith("0x") ? privateKey.slice(2) : privateKey;
|
|
13
|
+
return Buffer.from(privateKeyHex, "hex");
|
|
14
|
+
}
|
|
15
|
+
function parseEncryptedDataBuffer(encryptedBuffer) {
|
|
16
|
+
return {
|
|
17
|
+
iv: encryptedBuffer.slice(0, 16),
|
|
18
|
+
ephemPublicKey: encryptedBuffer.slice(16, 81),
|
|
19
|
+
// 65 bytes for uncompressed public key
|
|
20
|
+
ciphertext: encryptedBuffer.slice(81, -32),
|
|
21
|
+
mac: encryptedBuffer.slice(-32)
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// src/platform/shared/pgp-utils.ts
|
|
26
|
+
var STANDARD_PGP_CONFIG = {
|
|
27
|
+
preferredCompressionAlgorithm: 2,
|
|
28
|
+
// zlib (openpgp.enums.compression.zlib)
|
|
29
|
+
preferredSymmetricAlgorithm: 7
|
|
30
|
+
// aes256 (openpgp.enums.symmetric.aes256)
|
|
31
|
+
};
|
|
32
|
+
function processPGPKeyOptions(options) {
|
|
33
|
+
return {
|
|
34
|
+
name: options?.name || "Vana User",
|
|
35
|
+
email: options?.email || "user@vana.org",
|
|
36
|
+
passphrase: options?.passphrase
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function getPGPKeyGenParams(options) {
|
|
40
|
+
const { name, email, passphrase } = processPGPKeyOptions(options);
|
|
41
|
+
return {
|
|
42
|
+
type: "rsa",
|
|
43
|
+
rsaBits: 2048,
|
|
44
|
+
userIDs: [{ name, email }],
|
|
45
|
+
passphrase,
|
|
46
|
+
config: STANDARD_PGP_CONFIG
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// src/platform/shared/error-utils.ts
|
|
51
|
+
function wrapCryptoError(operation, error) {
|
|
52
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
53
|
+
return new Error(`${operation} failed: ${message}`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/utils/lazy-import.ts
|
|
57
|
+
function lazyImport(importFn) {
|
|
58
|
+
let cached = null;
|
|
59
|
+
return () => {
|
|
60
|
+
if (!cached) {
|
|
61
|
+
cached = importFn().catch((err) => {
|
|
62
|
+
cached = null;
|
|
63
|
+
throw new Error("Failed to load module", { cause: err });
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return cached;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// src/platform/browser.ts
|
|
71
|
+
var getOpenPGP = lazyImport(() => import("openpgp"));
|
|
72
|
+
var BrowserCryptoAdapter = class {
|
|
73
|
+
async encryptWithPublicKey(data, publicKeyHex) {
|
|
74
|
+
try {
|
|
75
|
+
const eccrypto = await import("eccrypto-js");
|
|
76
|
+
const publicKeyBuffer = Buffer.from(publicKeyHex, "hex");
|
|
77
|
+
const encrypted = await eccrypto.encrypt(
|
|
78
|
+
publicKeyBuffer,
|
|
79
|
+
Buffer.from(data, "utf8")
|
|
80
|
+
);
|
|
81
|
+
const result = Buffer.concat([
|
|
82
|
+
encrypted.iv,
|
|
83
|
+
encrypted.ephemPublicKey,
|
|
84
|
+
encrypted.ciphertext,
|
|
85
|
+
encrypted.mac
|
|
86
|
+
]);
|
|
87
|
+
return result.toString("hex");
|
|
88
|
+
} catch (error) {
|
|
89
|
+
throw new Error(`Encryption failed: ${error}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async decryptWithPrivateKey(encryptedData, privateKeyHex) {
|
|
93
|
+
try {
|
|
94
|
+
const eccrypto = await import("eccrypto-js");
|
|
95
|
+
const privateKeyBuffer = processWalletPrivateKey(privateKeyHex);
|
|
96
|
+
const encryptedBuffer = Buffer.from(encryptedData, "hex");
|
|
97
|
+
const { iv, ephemPublicKey, ciphertext, mac } = parseEncryptedDataBuffer(encryptedBuffer);
|
|
98
|
+
const encryptedObj = { iv, ephemPublicKey, ciphertext, mac };
|
|
99
|
+
const decryptedBuffer = await eccrypto.decrypt(
|
|
100
|
+
privateKeyBuffer,
|
|
101
|
+
encryptedObj
|
|
102
|
+
);
|
|
103
|
+
return decryptedBuffer.toString("utf8");
|
|
104
|
+
} catch (error) {
|
|
105
|
+
throw new Error(`Decryption failed: ${error}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async generateKeyPair() {
|
|
109
|
+
try {
|
|
110
|
+
const eccrypto = await import("eccrypto-js");
|
|
111
|
+
const privateKeyBytes = new Uint8Array(32);
|
|
112
|
+
crypto.getRandomValues(privateKeyBytes);
|
|
113
|
+
const privateKey = Buffer.from(privateKeyBytes);
|
|
114
|
+
const publicKey = eccrypto.getPublicCompressed(privateKey);
|
|
115
|
+
return {
|
|
116
|
+
privateKey: privateKey.toString("hex"),
|
|
117
|
+
publicKey: publicKey.toString("hex")
|
|
118
|
+
};
|
|
119
|
+
} catch (error) {
|
|
120
|
+
throw wrapCryptoError("key generation", error);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async encryptWithWalletPublicKey(data, publicKey) {
|
|
124
|
+
try {
|
|
125
|
+
const eccrypto = await import("eccrypto-js");
|
|
126
|
+
const uncompressedKey = processWalletPublicKey(publicKey);
|
|
127
|
+
const encryptedBuffer = await eccrypto.encrypt(
|
|
128
|
+
uncompressedKey,
|
|
129
|
+
Buffer.from(data)
|
|
130
|
+
);
|
|
131
|
+
const result = Buffer.concat([
|
|
132
|
+
encryptedBuffer.iv,
|
|
133
|
+
encryptedBuffer.ephemPublicKey,
|
|
134
|
+
encryptedBuffer.ciphertext,
|
|
135
|
+
encryptedBuffer.mac
|
|
136
|
+
]);
|
|
137
|
+
return result.toString("hex");
|
|
138
|
+
} catch (error) {
|
|
139
|
+
throw wrapCryptoError("encrypt with wallet public key", error);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
async decryptWithWalletPrivateKey(encryptedData, privateKey) {
|
|
143
|
+
try {
|
|
144
|
+
const eccrypto = await import("eccrypto-js");
|
|
145
|
+
const privateKeyBuffer = processWalletPrivateKey(privateKey);
|
|
146
|
+
const encryptedBuffer = Buffer.from(encryptedData, "hex");
|
|
147
|
+
const { iv, ephemPublicKey, ciphertext, mac } = parseEncryptedDataBuffer(encryptedBuffer);
|
|
148
|
+
const encryptedObj = { iv, ephemPublicKey, ciphertext, mac };
|
|
149
|
+
const decryptedBuffer = await eccrypto.decrypt(
|
|
150
|
+
privateKeyBuffer,
|
|
151
|
+
encryptedObj
|
|
152
|
+
);
|
|
153
|
+
return decryptedBuffer.toString("utf8");
|
|
154
|
+
} catch (error) {
|
|
155
|
+
throw wrapCryptoError("decrypt with wallet private key", error);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
async encryptWithPassword(data, password) {
|
|
159
|
+
try {
|
|
160
|
+
const openpgp = await getOpenPGP();
|
|
161
|
+
const message = await openpgp.createMessage({
|
|
162
|
+
binary: data
|
|
163
|
+
});
|
|
164
|
+
const encrypted = await openpgp.encrypt({
|
|
165
|
+
message,
|
|
166
|
+
passwords: [password],
|
|
167
|
+
format: "binary"
|
|
168
|
+
});
|
|
169
|
+
const response = new Response(encrypted);
|
|
170
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
171
|
+
return new Uint8Array(arrayBuffer);
|
|
172
|
+
} catch (error) {
|
|
173
|
+
throw new Error(`Failed to encrypt with password: ${error}`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
async decryptWithPassword(encryptedData, password) {
|
|
177
|
+
try {
|
|
178
|
+
const openpgp = await getOpenPGP();
|
|
179
|
+
const message = await openpgp.readMessage({
|
|
180
|
+
binaryMessage: encryptedData
|
|
181
|
+
});
|
|
182
|
+
const { data: decrypted } = await openpgp.decrypt({
|
|
183
|
+
message,
|
|
184
|
+
passwords: [password],
|
|
185
|
+
format: "binary"
|
|
186
|
+
});
|
|
187
|
+
return new Uint8Array(decrypted);
|
|
188
|
+
} catch (error) {
|
|
189
|
+
throw new Error(`Failed to decrypt with password: ${error}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
var BrowserPGPAdapter = class {
|
|
194
|
+
async encrypt(data, publicKeyArmored) {
|
|
195
|
+
try {
|
|
196
|
+
const openpgp = await getOpenPGP();
|
|
197
|
+
const publicKey = await openpgp.readKey({ armoredKey: publicKeyArmored });
|
|
198
|
+
const encrypted = await openpgp.encrypt({
|
|
199
|
+
message: await openpgp.createMessage({ text: data }),
|
|
200
|
+
encryptionKeys: publicKey,
|
|
201
|
+
config: {
|
|
202
|
+
preferredCompressionAlgorithm: openpgp.enums.compression.zlib
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
return encrypted;
|
|
206
|
+
} catch (error) {
|
|
207
|
+
throw new Error(`PGP encryption failed: ${error}`);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
async decrypt(encryptedData, privateKeyArmored) {
|
|
211
|
+
try {
|
|
212
|
+
const openpgp = await getOpenPGP();
|
|
213
|
+
const privateKey = await openpgp.readPrivateKey({
|
|
214
|
+
armoredKey: privateKeyArmored
|
|
215
|
+
});
|
|
216
|
+
const message = await openpgp.readMessage({
|
|
217
|
+
armoredMessage: encryptedData
|
|
218
|
+
});
|
|
219
|
+
const { data: decrypted } = await openpgp.decrypt({
|
|
220
|
+
message,
|
|
221
|
+
decryptionKeys: privateKey
|
|
222
|
+
});
|
|
223
|
+
return decrypted;
|
|
224
|
+
} catch (error) {
|
|
225
|
+
throw new Error(`PGP decryption failed: ${error}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
async generateKeyPair(options) {
|
|
229
|
+
try {
|
|
230
|
+
const openpgp = await getOpenPGP();
|
|
231
|
+
const keyGenParams = getPGPKeyGenParams(options);
|
|
232
|
+
const { privateKey, publicKey } = await openpgp.generateKey(keyGenParams);
|
|
233
|
+
return { publicKey, privateKey };
|
|
234
|
+
} catch (error) {
|
|
235
|
+
throw wrapCryptoError("PGP key generation", error);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
var BrowserHttpAdapter = class {
|
|
240
|
+
async fetch(url, options) {
|
|
241
|
+
if (typeof fetch === "undefined") {
|
|
242
|
+
throw new Error("Fetch API not available in this browser environment");
|
|
243
|
+
}
|
|
244
|
+
return fetch(url, options);
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
var BrowserCacheAdapter = class {
|
|
248
|
+
constructor() {
|
|
249
|
+
__publicField(this, "prefix", "vana_cache_");
|
|
250
|
+
}
|
|
251
|
+
get(key) {
|
|
252
|
+
try {
|
|
253
|
+
if (typeof sessionStorage === "undefined") {
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
return sessionStorage.getItem(this.prefix + key);
|
|
257
|
+
} catch {
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
set(key, value) {
|
|
262
|
+
try {
|
|
263
|
+
if (typeof sessionStorage !== "undefined") {
|
|
264
|
+
sessionStorage.setItem(this.prefix + key, value);
|
|
265
|
+
}
|
|
266
|
+
} catch {
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
delete(key) {
|
|
270
|
+
try {
|
|
271
|
+
if (typeof sessionStorage !== "undefined") {
|
|
272
|
+
sessionStorage.removeItem(this.prefix + key);
|
|
273
|
+
}
|
|
274
|
+
} catch {
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
clear() {
|
|
278
|
+
try {
|
|
279
|
+
if (typeof sessionStorage === "undefined") {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
const keys = Object.keys(sessionStorage);
|
|
283
|
+
for (const key of keys) {
|
|
284
|
+
if (key.startsWith(this.prefix)) {
|
|
285
|
+
sessionStorage.removeItem(key);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
} catch {
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
var BrowserPlatformAdapter = class {
|
|
293
|
+
constructor() {
|
|
294
|
+
__publicField(this, "crypto");
|
|
295
|
+
__publicField(this, "pgp");
|
|
296
|
+
__publicField(this, "http");
|
|
297
|
+
__publicField(this, "cache");
|
|
298
|
+
__publicField(this, "platform", "browser");
|
|
299
|
+
this.crypto = new BrowserCryptoAdapter();
|
|
300
|
+
this.pgp = new BrowserPGPAdapter();
|
|
301
|
+
this.http = new BrowserHttpAdapter();
|
|
302
|
+
this.cache = new BrowserCacheAdapter();
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
var browserPlatformAdapter = new BrowserPlatformAdapter();
|
|
306
|
+
export {
|
|
307
|
+
BrowserPlatformAdapter
|
|
308
|
+
};
|
|
309
|
+
//# sourceMappingURL=browser.js.map
|