@opendatalabs/vana-sdk 0.1.0-alpha.8eb4e46 → 0.1.0-alpha.a145c3c

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.
@@ -34363,6 +34363,8 @@ var PermissionsController = class {
34363
34363
  * Revokes a previously granted permission.
34364
34364
  *
34365
34365
  * @param params - Parameters for revoking the permission
34366
+ * @param params.permissionId - Permission identifier as bigint for contract compatibility.
34367
+ * Obtain from permission grants via `getUserPermissionGrantsOnChain()`.
34366
34368
  * @returns Promise resolving to transaction hash
34367
34369
  * @example
34368
34370
  * ```typescript
@@ -35504,8 +35506,7 @@ var DataController = class {
35504
35506
  schemaId,
35505
35507
  permissions = [],
35506
35508
  encrypt: encrypt3 = true,
35507
- providerName,
35508
- owner
35509
+ providerName
35509
35510
  } = params;
35510
35511
  try {
35511
35512
  let blob;
@@ -35583,7 +35584,7 @@ var DataController = class {
35583
35584
  filename,
35584
35585
  providerName
35585
35586
  );
35586
- const userAddress = owner || await this.getUserAddress();
35587
+ const userAddress = await this.getUserAddress();
35587
35588
  let encryptedPermissions = [];
35588
35589
  if (permissions.length > 0 && encrypt3) {
35589
35590
  const userEncryptionKey = await generateEncryptionKey(
@@ -35617,8 +35618,7 @@ var DataController = class {
35617
35618
  url: uploadResult.url,
35618
35619
  userAddress,
35619
35620
  permissions: encryptedPermissions,
35620
- schemaId: schemaId || 0,
35621
- ownerAddress: owner
35621
+ schemaId: schemaId || 0
35622
35622
  }
35623
35623
  );
35624
35624
  } else if (this.context.relayerCallbacks?.submitFileAddition) {
@@ -37879,6 +37879,39 @@ var ServerController = class {
37879
37879
  this.context = context;
37880
37880
  }
37881
37881
  PERSONAL_SERVER_BASE_URL = process.env.NEXT_PUBLIC_PERSONAL_SERVER_BASE_URL;
37882
+ /**
37883
+ * Retrieves the cryptographic identity of a personal server.
37884
+ *
37885
+ * @remarks
37886
+ * This method fetches the public key and metadata for a personal server,
37887
+ * which is required for encrypting data before sharing with the server.
37888
+ * The identity includes the server's public key, address, and operational
37889
+ * details needed for secure communication. This information is cached
37890
+ * by identity servers to enable offline key retrieval.
37891
+ *
37892
+ * @param request - Parameters containing the user address
37893
+ * @param request.userAddress - The wallet address associated with the personal server
37894
+ * @returns Promise resolving to the server's identity information
37895
+ * @throws {NetworkError} When the identity service is unavailable or returns invalid data
37896
+ * @throws {PersonalServerError} When server identity cannot be retrieved
37897
+ * @example
37898
+ * ```typescript
37899
+ * // Get server identity for data encryption
37900
+ * const identity = await vana.server.getIdentity({
37901
+ * userAddress: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36"
37902
+ * });
37903
+ *
37904
+ * console.log(`Server: ${identity.name}`);
37905
+ * console.log(`Address: ${identity.address}`);
37906
+ * console.log(`Public Key: ${identity.public_key}`);
37907
+ *
37908
+ * // Use the public key for encrypting data to share with this server
37909
+ * const encryptedData = await encryptWithWalletPublicKey(
37910
+ * userData,
37911
+ * identity.public_key
37912
+ * );
37913
+ * ```
37914
+ */
37882
37915
  async getIdentity(request) {
37883
37916
  try {
37884
37917
  const response = await fetch(
@@ -37921,10 +37954,13 @@ var ServerController = class {
37921
37954
  * This method submits a computation request to the personal server API.
37922
37955
  * The response includes the operation ID.
37923
37956
  * @param params - The request parameters object
37924
- * @param params.permissionId - The permission ID authorizing this operation
37957
+ * @param params.permissionId - The permission ID authorizing this operation.
37958
+ * Obtain from granted permissions via `vana.permissions.getUserPermissionGrantsOnChain()`.
37925
37959
  * @returns A Promise that resolves to an operation response with status and control URLs
37926
- * @throws {PersonalServerError} When server request fails or parameters are invalid
37927
- * @throws {NetworkError} When personal server API communication fails
37960
+ * @throws {PersonalServerError} When server request fails or parameters are invalid.
37961
+ * Verify permissionId exists and is active for the target server.
37962
+ * @throws {NetworkError} When personal server API communication fails.
37963
+ * Check server URL configuration and network connectivity.
37928
37964
  * @example
37929
37965
  * ```typescript
37930
37966
  * const response = await vana.server.createOperation({
@@ -38026,6 +38062,50 @@ var ServerController = class {
38026
38062
  );
38027
38063
  }
38028
38064
  }
38065
+ /**
38066
+ * Cancels a running operation on the personal server.
38067
+ *
38068
+ * @remarks
38069
+ * This method attempts to cancel an operation that is currently processing
38070
+ * on the personal server. The operation must be in a cancellable state
38071
+ * (typically `starting` or `processing`). Not all operations support
38072
+ * cancellation, and cancellation may not be immediate. The server will
38073
+ * attempt to stop the operation and update its status to `canceled`.
38074
+ *
38075
+ * **Cancellation Behavior:**
38076
+ * - Operations in `succeeded` or `failed` states cannot be canceled
38077
+ * - Some long-running operations may take time to respond to cancellation
38078
+ * - Always verify cancellation by polling the operation status afterward
38079
+ *
38080
+ * @param operationId - The unique identifier of the operation to cancel,
38081
+ * obtained from `createOperation()` response
38082
+ * @returns Promise that resolves when the cancellation request is accepted
38083
+ * @throws {PersonalServerError} When the operation cannot be canceled or doesn't exist.
38084
+ * Check operation status - it may already be completed or failed.
38085
+ * @throws {NetworkError} When unable to reach the personal server API.
38086
+ * Verify server URL and network connectivity.
38087
+ * @example
38088
+ * ```typescript
38089
+ * // Start a long-running operation
38090
+ * const operation = await vana.server.createOperation({
38091
+ * permissionId: 123
38092
+ * });
38093
+ *
38094
+ * // Cancel if needed
38095
+ * try {
38096
+ * await vana.server.cancelOperation(operation.id);
38097
+ * console.log("Cancellation requested");
38098
+ *
38099
+ * // Verify cancellation
38100
+ * const status = await vana.server.getOperation(operation.id);
38101
+ * if (status.status === "canceled") {
38102
+ * console.log("Operation successfully canceled");
38103
+ * }
38104
+ * } catch (error) {
38105
+ * console.error("Failed to cancel:", error);
38106
+ * }
38107
+ * ```
38108
+ */
38029
38109
  async cancelOperation(operationId) {
38030
38110
  try {
38031
38111
  const response = await fetch(
@@ -38329,7 +38409,8 @@ var ProtocolController = class {
38329
38409
  * are actually deployed on the current network.
38330
38410
  * @param contractName - The name of the Vana contract to retrieve (use const assertion for full typing)
38331
38411
  * @returns An object containing the contract's address and fully typed ABI
38332
- * @throws {ContractNotFoundError} When the contract is not deployed on the current chain
38412
+ * @throws {ContractNotFoundError} When the contract is not deployed on the current chain.
38413
+ * Verify contract name spelling and check current network with `getChainId()`.
38333
38414
  * @example
38334
38415
  * ```typescript
38335
38416
  * // Get contract info with full type inference
@@ -39513,151 +39594,175 @@ var PinataStorage = class {
39513
39594
  }
39514
39595
  };
39515
39596
 
39516
- // src/storage/providers/callback-storage.ts
39517
- var CallbackStorage = class {
39518
- constructor(callbacks) {
39519
- this.callbacks = callbacks;
39520
- if (!callbacks.upload || !callbacks.download) {
39521
- throw new Error(
39522
- "CallbackStorage requires both upload and download callbacks"
39597
+ // src/storage/providers/server-proxy.ts
39598
+ var ServerProxyStorage = class {
39599
+ constructor(config) {
39600
+ this.config = config;
39601
+ if (!config.uploadUrl) {
39602
+ throw new StorageError(
39603
+ "Upload URL is required",
39604
+ "MISSING_UPLOAD_URL",
39605
+ "server-proxy"
39606
+ );
39607
+ }
39608
+ if (!config.downloadUrl) {
39609
+ throw new StorageError(
39610
+ "Download URL is required",
39611
+ "MISSING_DOWNLOAD_URL",
39612
+ "server-proxy"
39523
39613
  );
39524
39614
  }
39525
39615
  }
39526
39616
  /**
39527
- * Upload a file using the provided callback
39617
+ * Uploads a file through your server endpoint
39528
39618
  *
39529
- * @param file - The blob to upload
39530
- * @param filename - Optional filename for the upload
39531
- * @returns The upload result with URL and metadata
39619
+ * @remarks
39620
+ * This method sends the file to your configured upload endpoint via FormData.
39621
+ * Your server is responsible for handling the actual storage implementation
39622
+ * and must return a JSON response with `success: true` and an `identifier` field.
39623
+ *
39624
+ * @param file - The file to upload
39625
+ * @param filename - Optional custom filename
39626
+ * @returns Promise that resolves to the server-provided identifier
39627
+ * @throws {StorageError} When the upload fails or server returns an error
39628
+ *
39629
+ * @example
39630
+ * ```typescript
39631
+ * const identifier = await serverStorage.upload(fileBlob, { name: "report.pdf" });
39632
+ * console.log("File uploaded with identifier:", identifier);
39633
+ * ```
39532
39634
  */
39533
39635
  async upload(file, filename) {
39534
39636
  try {
39535
- const result = await this.callbacks.upload(file, filename);
39536
- if (!result.url || result.url.trim() === "") {
39637
+ const formData = new FormData();
39638
+ formData.append("file", file);
39639
+ if (filename) {
39640
+ formData.append("name", filename);
39641
+ }
39642
+ const response = await fetch(this.config.uploadUrl, {
39643
+ method: "POST",
39644
+ body: formData
39645
+ });
39646
+ if (!response.ok) {
39647
+ const _errorText = await response.text();
39537
39648
  throw new StorageError(
39538
- "Upload callback returned invalid result: missing or empty url",
39539
- "INVALID_UPLOAD_RESULT",
39540
- "callback-storage"
39649
+ `Server upload failed: ${response.status} ${response.statusText}`,
39650
+ "UPLOAD_FAILED",
39651
+ "server-proxy"
39541
39652
  );
39542
39653
  }
39543
- return result;
39654
+ const result = await response.json();
39655
+ if (!result.success) {
39656
+ throw new StorageError(
39657
+ `Upload failed: ${result.error || "Unknown server error"}`,
39658
+ "UPLOAD_FAILED",
39659
+ "server-proxy"
39660
+ );
39661
+ }
39662
+ if (!result.identifier) {
39663
+ throw new StorageError(
39664
+ "Server upload succeeded but no identifier returned",
39665
+ "NO_IDENTIFIER_RETURNED",
39666
+ "server-proxy"
39667
+ );
39668
+ }
39669
+ return {
39670
+ url: result.url || result.identifier,
39671
+ size: file.size,
39672
+ contentType: file.type || "application/octet-stream"
39673
+ };
39544
39674
  } catch (error) {
39545
39675
  if (error instanceof StorageError) {
39546
39676
  throw error;
39547
39677
  }
39548
39678
  throw new StorageError(
39549
- `Upload failed: ${error instanceof Error ? error.message : String(error)}`,
39679
+ `Server proxy upload error: ${error instanceof Error ? error.message : "Unknown error"}`,
39550
39680
  "UPLOAD_ERROR",
39551
- "callback-storage",
39552
- { cause: error instanceof Error ? error : void 0 }
39681
+ "server-proxy"
39553
39682
  );
39554
39683
  }
39555
39684
  }
39556
39685
  /**
39557
- * Download a file using the provided callback
39686
+ * Downloads a file through your server endpoint
39558
39687
  *
39559
- * @param url - The URL or identifier to download
39560
- * @returns The downloaded blob
39688
+ * @remarks
39689
+ * This method sends the identifier to your configured download endpoint via POST request.
39690
+ * Your server is responsible for retrieving the file from your storage backend
39691
+ * and returning the file content as a blob response.
39692
+ *
39693
+ * @param url - The server-provided URL or identifier from upload
39694
+ * @returns Promise that resolves to the downloaded file content
39695
+ * @throws {StorageError} When the download fails or file is not found
39696
+ *
39697
+ * @example
39698
+ * ```typescript
39699
+ * const fileBlob = await serverStorage.download("file-123");
39700
+ * const url = URL.createObjectURL(fileBlob);
39701
+ * ```
39561
39702
  */
39562
39703
  async download(url) {
39563
39704
  try {
39564
- const identifier = this.callbacks.extractIdentifier ? this.callbacks.extractIdentifier(url) : url;
39565
- const blob = await this.callbacks.download(identifier);
39566
- if (!(blob instanceof Blob)) {
39705
+ const identifier = this.extractIdentifierFromUrl(url);
39706
+ const response = await fetch(this.config.downloadUrl, {
39707
+ method: "POST",
39708
+ headers: {
39709
+ "Content-Type": "application/json"
39710
+ },
39711
+ body: JSON.stringify({ identifier })
39712
+ });
39713
+ if (!response.ok) {
39714
+ const _errorText = await response.text();
39567
39715
  throw new StorageError(
39568
- "Download callback returned invalid result: expected Blob",
39569
- "INVALID_DOWNLOAD_RESULT",
39570
- "callback-storage"
39716
+ `Server download failed: ${response.status} ${response.statusText}`,
39717
+ "DOWNLOAD_FAILED",
39718
+ "server-proxy"
39571
39719
  );
39572
39720
  }
39573
- return blob;
39721
+ return await response.blob();
39574
39722
  } catch (error) {
39575
39723
  if (error instanceof StorageError) {
39576
39724
  throw error;
39577
39725
  }
39578
39726
  throw new StorageError(
39579
- `Download failed: ${error instanceof Error ? error.message : String(error)}`,
39727
+ `Server proxy download error: ${error instanceof Error ? error.message : "Unknown error"}`,
39580
39728
  "DOWNLOAD_ERROR",
39581
- "callback-storage",
39582
- { cause: error instanceof Error ? error : void 0 }
39729
+ "server-proxy"
39583
39730
  );
39584
39731
  }
39585
39732
  }
39586
- /**
39587
- * List files using the provided callback (if available)
39588
- *
39589
- * @param options - Optional list options including filters and pagination
39590
- * @returns Array of storage files
39591
- */
39592
- async list(options) {
39593
- if (!this.callbacks.list) {
39594
- throw new StorageError(
39595
- "List operation not supported - no list callback provided",
39596
- "NOT_SUPPORTED",
39597
- "callback-storage"
39598
- );
39599
- }
39600
- try {
39601
- const result = await this.callbacks.list(options?.namePattern, options);
39602
- return result.items.map((item, index) => ({
39603
- id: item.identifier,
39604
- name: item.identifier.split("/").pop() || `file-${index}`,
39605
- url: item.identifier,
39606
- size: item.size || 0,
39607
- contentType: "application/octet-stream",
39608
- createdAt: item.lastModified || /* @__PURE__ */ new Date(),
39609
- metadata: item.metadata
39610
- }));
39611
- } catch (error) {
39612
- throw new StorageError(
39613
- `List failed: ${error instanceof Error ? error.message : String(error)}`,
39614
- "LIST_ERROR",
39615
- "callback-storage",
39616
- { cause: error instanceof Error ? error : void 0 }
39617
- );
39618
- }
39733
+ async list(_options) {
39734
+ throw new StorageError(
39735
+ "List operation is not supported by server proxy storage",
39736
+ "LIST_NOT_SUPPORTED",
39737
+ "server-proxy"
39738
+ );
39619
39739
  }
39620
- /**
39621
- * Delete a file using the provided callback (if available)
39622
- *
39623
- * @param url - The URL or identifier to delete
39624
- * @returns True if deletion succeeded
39625
- */
39626
- async delete(url) {
39627
- if (!this.callbacks.delete) {
39628
- throw new StorageError(
39629
- "Delete operation not supported - no delete callback provided",
39630
- "NOT_SUPPORTED",
39631
- "callback-storage"
39632
- );
39633
- }
39634
- try {
39635
- const identifier = this.callbacks.extractIdentifier ? this.callbacks.extractIdentifier(url) : url;
39636
- return await this.callbacks.delete(identifier);
39637
- } catch (error) {
39638
- throw new StorageError(
39639
- `Delete failed: ${error instanceof Error ? error.message : String(error)}`,
39640
- "DELETE_ERROR",
39641
- "callback-storage",
39642
- { cause: error instanceof Error ? error : void 0 }
39643
- );
39644
- }
39740
+ async delete(_url) {
39741
+ throw new StorageError(
39742
+ "Delete operation is not supported by server proxy storage",
39743
+ "DELETE_NOT_SUPPORTED",
39744
+ "server-proxy"
39745
+ );
39645
39746
  }
39646
39747
  /**
39647
- * Get provider configuration
39748
+ * Extract identifier from URL or return as-is
39648
39749
  *
39649
- * @returns Provider configuration metadata
39750
+ * @param url - URL or identifier string
39751
+ * @returns identifier string
39650
39752
  */
39753
+ extractIdentifierFromUrl(url) {
39754
+ return url;
39755
+ }
39651
39756
  getConfig() {
39652
39757
  return {
39653
- name: "callback-storage",
39654
- type: "callback",
39758
+ name: "Server Proxy",
39759
+ type: "server-proxy",
39655
39760
  requiresAuth: false,
39656
39761
  features: {
39657
39762
  upload: true,
39658
39763
  download: true,
39659
- list: !!this.callbacks.list,
39660
- delete: !!this.callbacks.delete
39764
+ list: false,
39765
+ delete: false
39661
39766
  }
39662
39767
  };
39663
39768
  }
@@ -40279,15 +40384,35 @@ var VanaCore = class {
40279
40384
  }
40280
40385
  /**
40281
40386
  * Encrypts data using the Vana protocol standard encryption.
40282
- * This method automatically uses the correct platform adapter for the current environment.
40387
+ *
40388
+ * @remarks
40389
+ * This method implements the Vana network's standard encryption protocol using
40390
+ * platform-appropriate cryptographic libraries. It automatically handles different
40391
+ * input types (string or Blob) and produces encrypted output suitable for secure
40392
+ * storage or transmission. The encryption is compatible with the network's
40393
+ * decryption protocols and can be decrypted by authorized parties.
40283
40394
  *
40284
- * @param data The data to encrypt (string or Blob)
40285
- * @param key The key to use as encryption key
40286
- * @returns The encrypted data as Blob
40395
+ * @param data - The data to encrypt (string or Blob)
40396
+ * @param key - The encryption key (typically generated via `generateEncryptionKey`)
40397
+ * @returns The encrypted data as a Blob
40398
+ * @throws {Error} When encryption fails due to invalid key or data format
40287
40399
  * @example
40288
40400
  * ```typescript
40289
- * const encryptionKey = await generateEncryptionKey(walletClient);
40290
- * const encrypted = await vana.encryptBlob("sensitive data", encryptionKey);
40401
+ * import { generateEncryptionKey } from '@opendatalabs/vana-sdk/node';
40402
+ *
40403
+ * // Generate encryption key from wallet signature
40404
+ * const encryptionKey = await generateEncryptionKey(vana.walletClient);
40405
+ *
40406
+ * // Encrypt string data
40407
+ * const sensitiveData = "User's private information";
40408
+ * const encrypted = await vana.encryptBlob(sensitiveData, encryptionKey);
40409
+ *
40410
+ * // Encrypt file data
40411
+ * const fileBlob = new Blob([fileContent], { type: 'application/json' });
40412
+ * const encryptedFile = await vana.encryptBlob(fileBlob, encryptionKey);
40413
+ *
40414
+ * // Store encrypted data safely
40415
+ * await storageProvider.upload(encrypted, 'encrypted-data.bin');
40291
40416
  * ```
40292
40417
  */
40293
40418
  async encryptBlob(data, key) {
@@ -40295,16 +40420,52 @@ var VanaCore = class {
40295
40420
  }
40296
40421
  /**
40297
40422
  * Decrypts data that was encrypted using the Vana protocol.
40298
- * This method automatically uses the correct platform adapter for the current environment.
40423
+ *
40424
+ * @remarks
40425
+ * This method decrypts data that was previously encrypted using the Vana network's
40426
+ * standard encryption protocol. It requires the same wallet signature that was used
40427
+ * for encryption and automatically uses the appropriate platform adapter for
40428
+ * cryptographic operations. The decrypted output maintains the original data format.
40299
40429
  *
40300
- * @param encryptedData The encrypted data (string or Blob)
40301
- * @param walletSignature The wallet signature to use as decryption key
40302
- * @returns The decrypted data as Blob
40430
+ * @param encryptedData - The encrypted data (string or Blob)
40431
+ * @param walletSignature - The wallet signature used as decryption key
40432
+ * @returns The decrypted data as a Blob
40433
+ * @throws {Error} When decryption fails due to invalid signature or corrupted data
40303
40434
  * @example
40304
40435
  * ```typescript
40305
- * const encryptionKey = await generateEncryptionKey(walletClient);
40306
- * const decrypted = await vana.decryptBlob(encryptedData, encryptionKey);
40307
- * const text = await decrypted.text();
40436
+ * import { generateEncryptionKey } from '@opendatalabs/vana-sdk/node';
40437
+ *
40438
+ * // Retrieve encrypted data from storage
40439
+ * const encryptedBlob = await storageProvider.download('encrypted-data.bin');
40440
+ *
40441
+ * // Generate the same key used for encryption
40442
+ * const decryptionKey = await generateEncryptionKey(vana.walletClient);
40443
+ *
40444
+ * // Decrypt the data
40445
+ * const decrypted = await vana.decryptBlob(encryptedBlob, decryptionKey);
40446
+ *
40447
+ * // Convert back to original format
40448
+ * const originalText = await decrypted.text();
40449
+ * const originalJson = JSON.parse(originalText);
40450
+ *
40451
+ * console.log('Decrypted data:', originalJson);
40452
+ * ```
40453
+ *
40454
+ * @example
40455
+ * ```typescript
40456
+ * // Decrypt file downloaded from Vana network
40457
+ * const userFiles = await vana.data.getUserFiles();
40458
+ * const file = userFiles[0];
40459
+ *
40460
+ * // Download encrypted content
40461
+ * const encrypted = await fetch(file.url).then(r => r.blob());
40462
+ *
40463
+ * // Decrypt with user's key
40464
+ * const decryptionKey = await generateEncryptionKey(vana.walletClient);
40465
+ * const decrypted = await vana.decryptBlob(encrypted, decryptionKey);
40466
+ *
40467
+ * // Process original data
40468
+ * const fileContent = await decrypted.arrayBuffer();
40308
40469
  * ```
40309
40470
  */
40310
40471
  async decryptBlob(encryptedData, walletSignature) {
@@ -41221,7 +41382,6 @@ export {
41221
41382
  BaseController,
41222
41383
  BlockchainError,
41223
41384
  BrowserPlatformAdapter,
41224
- CallbackStorage,
41225
41385
  CircuitBreaker,
41226
41386
  ContractFactory,
41227
41387
  ContractNotFoundError,
@@ -41256,6 +41416,7 @@ export {
41256
41416
  SchemaValidator,
41257
41417
  SerializationError,
41258
41418
  ServerController,
41419
+ ServerProxyStorage,
41259
41420
  ServerUrlMismatchError,
41260
41421
  SignatureError,
41261
41422
  StorageError,