@opendatalabs/vana-sdk 0.1.0-alpha.3bc04d8 → 0.1.0-alpha.3cd7595

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.
@@ -176,17 +176,178 @@ var init_dataSchema_schema = __esm({
176
176
  }
177
177
  });
178
178
 
179
+ // src/utils/ipfs.ts
180
+ var ipfs_exports = {};
181
+ __export(ipfs_exports, {
182
+ DEFAULT_IPFS_GATEWAY: () => DEFAULT_IPFS_GATEWAY,
183
+ IPFS_GATEWAYS: () => IPFS_GATEWAYS,
184
+ convertIpfsUrl: () => convertIpfsUrl,
185
+ convertIpfsUrlWithFallbacks: () => convertIpfsUrlWithFallbacks,
186
+ extractIpfsHash: () => extractIpfsHash,
187
+ fetchWithFallbacks: () => fetchWithFallbacks,
188
+ getGatewayUrls: () => getGatewayUrls,
189
+ isIpfsUrl: () => isIpfsUrl
190
+ });
191
+ function isIpfsUrl(url) {
192
+ return url.startsWith("ipfs://");
193
+ }
194
+ function convertIpfsUrl(url, gateway = DEFAULT_IPFS_GATEWAY) {
195
+ if (isIpfsUrl(url)) {
196
+ const hash = url.replace("ipfs://", "");
197
+ return `${gateway}${hash}`;
198
+ }
199
+ return url;
200
+ }
201
+ function extractIpfsHash(url) {
202
+ const patterns = [
203
+ /ipfs\/([a-zA-Z0-9]+)/,
204
+ // https://gateway.pinata.cloud/ipfs/HASH
205
+ /^ipfs:\/\/([a-zA-Z0-9]+)$/,
206
+ // ipfs://HASH
207
+ /^([a-zA-Z0-9]{46,})$/
208
+ // Just the hash (46+ chars for IPFS hashes)
209
+ ];
210
+ for (const pattern of patterns) {
211
+ const match = url.match(pattern);
212
+ if (match) {
213
+ return match[1];
214
+ }
215
+ }
216
+ return null;
217
+ }
218
+ function getGatewayUrls(hash) {
219
+ return IPFS_GATEWAYS.map((gateway) => `${gateway}${hash}`);
220
+ }
221
+ function convertIpfsUrlWithFallbacks(url) {
222
+ const hash = extractIpfsHash(url);
223
+ if (hash) {
224
+ return getGatewayUrls(hash);
225
+ }
226
+ return [url];
227
+ }
228
+ async function fetchWithFallbacks(url, options) {
229
+ const hash = extractIpfsHash(url);
230
+ if (!hash) {
231
+ return fetch(url, options);
232
+ }
233
+ const gatewayUrls = getGatewayUrls(hash);
234
+ let lastError = null;
235
+ for (let i = 0; i < gatewayUrls.length; i++) {
236
+ const gatewayUrl = gatewayUrls[i];
237
+ try {
238
+ const response = await fetch(gatewayUrl, {
239
+ ...options,
240
+ // Add timeout to avoid hanging on slow gateways
241
+ signal: AbortSignal.timeout(1e4)
242
+ // 10 second timeout
243
+ });
244
+ if (response.ok) {
245
+ return response;
246
+ }
247
+ if (response.status === 429) {
248
+ lastError = new Error(`Gateway rate limited: ${gatewayUrl}`);
249
+ continue;
250
+ }
251
+ lastError = new Error(`Gateway error ${response.status}: ${gatewayUrl}`);
252
+ } catch (error) {
253
+ lastError = error instanceof Error ? error : new Error(String(error));
254
+ if (lastError.message.includes("429") || lastError.name === "TimeoutError") {
255
+ continue;
256
+ }
257
+ }
258
+ if (i < gatewayUrls.length - 1) {
259
+ await new Promise((resolve) => setTimeout(resolve, 1e3 * (i + 1)));
260
+ }
261
+ }
262
+ throw new Error(
263
+ `All IPFS gateways failed for hash ${hash}. Last error: ${lastError?.message}`
264
+ );
265
+ }
266
+ var DEFAULT_IPFS_GATEWAY, IPFS_GATEWAYS;
267
+ var init_ipfs = __esm({
268
+ "src/utils/ipfs.ts"() {
269
+ "use strict";
270
+ DEFAULT_IPFS_GATEWAY = "https://dweb.link/ipfs/";
271
+ IPFS_GATEWAYS = [
272
+ "https://dweb.link/ipfs/",
273
+ // Interplanetary Shipyard - highly reliable
274
+ "https://ipfs.io/ipfs/",
275
+ // IPFS Foundation - reliable
276
+ "https://cloudflare-ipfs.com/ipfs/",
277
+ // Cloudflare - good performance
278
+ "https://gateway.pinata.cloud/ipfs/",
279
+ // Pinata - backup option (has rate limits)
280
+ "https://ipfs.filebase.io/ipfs/"
281
+ // Filebase - emerging reliable option
282
+ ];
283
+ }
284
+ });
285
+
286
+ // src/utils/download.ts
287
+ var download_exports = {};
288
+ __export(download_exports, {
289
+ fetchWithRelayer: () => fetchWithRelayer
290
+ });
291
+ async function fetchWithRelayer(url, downloadRelayer) {
292
+ let processedUrl = url;
293
+ if (url.startsWith("ar://")) {
294
+ const txId = url.replace("ar://", "");
295
+ processedUrl = `https://arweave.net/${txId}`;
296
+ }
297
+ const ipfsHash = extractIpfsHash(processedUrl);
298
+ if (ipfsHash) {
299
+ try {
300
+ return await fetchWithFallbacks(url);
301
+ } catch (ipfsError) {
302
+ if (downloadRelayer) {
303
+ try {
304
+ const gatewayUrl = `https://gateway.pinata.cloud/ipfs/${ipfsHash}`;
305
+ const blob = await downloadRelayer.proxyDownload(gatewayUrl);
306
+ return new Response(blob);
307
+ } catch {
308
+ throw ipfsError;
309
+ }
310
+ }
311
+ throw ipfsError;
312
+ }
313
+ }
314
+ try {
315
+ const response = await fetch(processedUrl);
316
+ return response;
317
+ } catch (error) {
318
+ if (downloadRelayer) {
319
+ try {
320
+ const blob = await downloadRelayer.proxyDownload(processedUrl);
321
+ return new Response(blob);
322
+ } catch {
323
+ throw error;
324
+ }
325
+ }
326
+ throw new Error(
327
+ `Failed to fetch from ${processedUrl}: ${error instanceof Error ? error.message : "Unknown error"}`
328
+ );
329
+ }
330
+ }
331
+ var init_download = __esm({
332
+ "src/utils/download.ts"() {
333
+ "use strict";
334
+ init_ipfs();
335
+ }
336
+ });
337
+
179
338
  // src/utils/schemaValidation.ts
180
339
  import Ajv from "ajv";
181
340
  import addFormats from "ajv-formats";
182
- function validateDataSchema(schema) {
183
- return schemaValidator.validateDataSchema(schema);
341
+ function validateDataSchemaAgainstMetaSchema(schema) {
342
+ const validator = schemaValidator;
343
+ validator.validateDataSchemaAgainstMetaSchema(schema);
344
+ return schema;
184
345
  }
185
346
  function validateDataAgainstSchema(data, schema) {
186
347
  return schemaValidator.validateDataAgainstSchema(data, schema);
187
348
  }
188
- function fetchAndValidateSchema(url) {
189
- return schemaValidator.fetchAndValidateSchema(url);
349
+ function fetchAndValidateSchema(url, downloadRelayer) {
350
+ return schemaValidator.fetchAndValidateSchema(url, downloadRelayer);
190
351
  }
191
352
  var SchemaValidationError, SchemaValidator, schemaValidator;
192
353
  var init_schemaValidation = __esm({
@@ -213,9 +374,9 @@ var init_schemaValidation = __esm({
213
374
  this.dataSchemaValidator = this.ajv.compile(dataSchema_schema_default);
214
375
  }
215
376
  /**
216
- * Validates a data schema against the Vana meta-schema
377
+ * Validates a data schema definition against the Vana meta-schema
217
378
  *
218
- * @param schema - The data schema to validate
379
+ * @param schema - The data schema definition to validate
219
380
  * @throws SchemaValidationError if invalid
220
381
  * @example
221
382
  * ```typescript
@@ -234,10 +395,10 @@ var init_schemaValidation = __esm({
234
395
  * }
235
396
  * };
236
397
  *
237
- * validator.validateDataSchema(schema); // throws if invalid
398
+ * validator.validateDataSchemaAgainstMetaSchema(schema); // throws if invalid
238
399
  * ```
239
400
  */
240
- validateDataSchema(schema) {
401
+ validateDataSchemaAgainstMetaSchema(schema) {
241
402
  const isValid = this.dataSchemaValidator(schema);
242
403
  if (!isValid) {
243
404
  const errors = this.dataSchemaValidator.errors || [];
@@ -257,10 +418,10 @@ var init_schemaValidation = __esm({
257
418
  }
258
419
  }
259
420
  /**
260
- * Validates data against a JSON Schema from a schema
421
+ * Validates data against a JSON Schema
261
422
  *
262
423
  * @param data - The data to validate
263
- * @param schema - The schema containing the validation rules (DataSchema or Schema)
424
+ * @param schema - The schema containing the validation rules (must have been validated or fetched from chain)
264
425
  * @throws SchemaValidationError if invalid
265
426
  * @example
266
427
  * ```typescript
@@ -270,25 +431,22 @@ var init_schemaValidation = __esm({
270
431
  * const schema = await vana.schemas.get(1);
271
432
  * validator.validateDataAgainstSchema(userData, schema);
272
433
  *
273
- * // Also works with DataSchema object
274
- * const dataSchema: DataSchema = {
434
+ * // Also works with pre-validated DataSchema object
435
+ * const dataSchema = validator.validateDataSchemaAgainstMetaSchema({
275
436
  * name: "User Profile",
276
437
  * version: "1.0.0",
277
438
  * dialect: "json",
278
439
  * schema: { type: "object", properties: { name: { type: "string" } } }
279
- * };
440
+ * });
280
441
  * validator.validateDataAgainstSchema(userData, dataSchema);
281
442
  * ```
282
443
  */
283
444
  validateDataAgainstSchema(data, schema) {
284
- if (!("id" in schema)) {
285
- this.validateDataSchema(schema);
286
- }
287
445
  if (schema.dialect !== "json") {
288
- throw new SchemaValidationError(
289
- `Data validation only supported for JSON dialect, got: ${schema.dialect}`,
290
- []
446
+ console.warn(
447
+ `[SchemaValidator] Data validation skipped: dialect '${schema.dialect}' does not support data validation. Only JSON schemas can validate data structure.`
291
448
  );
449
+ return;
292
450
  }
293
451
  if (typeof schema.schema !== "object") {
294
452
  throw new SchemaValidationError(
@@ -354,9 +512,11 @@ var init_schemaValidation = __esm({
354
512
  }
355
513
  }
356
514
  /**
357
- * Fetches and validates a schema from a URL
515
+ * Fetches and validates a data schema from a URL
358
516
  *
359
- * @param url - The URL to fetch the schema from
517
+ * @param url - The URL to fetch the data schema from
518
+ * @param downloadRelayer - Optional download relayer for CORS bypass
519
+ * @param downloadRelayer.proxyDownload - Function to proxy downloads through application server
360
520
  * @returns The validated data schema
361
521
  * @throws SchemaValidationError if invalid or fetch fails
362
522
  * @example
@@ -365,14 +525,15 @@ var init_schemaValidation = __esm({
365
525
  * const schema = await validator.fetchAndValidateSchema("https://example.com/schema.json");
366
526
  * ```
367
527
  */
368
- async fetchAndValidateSchema(url) {
528
+ async fetchAndValidateSchema(url, downloadRelayer) {
369
529
  try {
370
- const response = await fetch(url);
530
+ const { fetchWithRelayer: fetchWithRelayer2 } = await Promise.resolve().then(() => (init_download(), download_exports));
531
+ const response = await fetchWithRelayer2(url, downloadRelayer);
371
532
  if (!response.ok) {
372
533
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
373
534
  }
374
535
  const schema = await response.json();
375
- this.validateDataSchema(schema);
536
+ this.validateDataSchemaAgainstMetaSchema(schema);
376
537
  if (schema.dialect === "sqlite" && typeof schema.schema === "string") {
377
538
  this.validateSQLiteDDL(schema.schema, schema.dialectVersion);
378
539
  }
@@ -2790,6 +2951,19 @@ var init_DataRegistryImplementation = __esm({
2790
2951
  name: "Upgraded",
2791
2952
  type: "event"
2792
2953
  },
2954
+ {
2955
+ inputs: [],
2956
+ name: "DATA_PORTABILITY_ROLE",
2957
+ outputs: [
2958
+ {
2959
+ internalType: "bytes32",
2960
+ name: "",
2961
+ type: "bytes32"
2962
+ }
2963
+ ],
2964
+ stateMutability: "view",
2965
+ type: "function"
2966
+ },
2793
2967
  {
2794
2968
  inputs: [],
2795
2969
  name: "DEFAULT_ADMIN_ROLE",
@@ -2887,14 +3061,9 @@ var init_DataRegistryImplementation = __esm({
2887
3061
  {
2888
3062
  inputs: [
2889
3063
  {
2890
- internalType: "string",
2891
- name: "url",
2892
- type: "string"
2893
- },
2894
- {
2895
- internalType: "address",
2896
- name: "ownerAddress",
2897
- type: "address"
3064
+ internalType: "uint256",
3065
+ name: "fileId",
3066
+ type: "uint256"
2898
3067
  },
2899
3068
  {
2900
3069
  components: [
@@ -2912,16 +3081,15 @@ var init_DataRegistryImplementation = __esm({
2912
3081
  internalType: "struct IDataRegistry.Permission[]",
2913
3082
  name: "permissions",
2914
3083
  type: "tuple[]"
2915
- }
2916
- ],
2917
- name: "addFileWithPermissions",
2918
- outputs: [
3084
+ },
2919
3085
  {
2920
3086
  internalType: "uint256",
2921
- name: "",
3087
+ name: "schemaId",
2922
3088
  type: "uint256"
2923
3089
  }
2924
3090
  ],
3091
+ name: "addFilePermissionsAndSchema",
3092
+ outputs: [],
2925
3093
  stateMutability: "nonpayable",
2926
3094
  type: "function"
2927
3095
  },
@@ -2953,14 +3121,9 @@ var init_DataRegistryImplementation = __esm({
2953
3121
  internalType: "struct IDataRegistry.Permission[]",
2954
3122
  name: "permissions",
2955
3123
  type: "tuple[]"
2956
- },
2957
- {
2958
- internalType: "uint256",
2959
- name: "schemaId",
2960
- type: "uint256"
2961
3124
  }
2962
3125
  ],
2963
- name: "addFileWithPermissionsAndSchema",
3126
+ name: "addFileWithPermissions",
2964
3127
  outputs: [
2965
3128
  {
2966
3129
  internalType: "uint256",
@@ -2979,136 +3142,42 @@ var init_DataRegistryImplementation = __esm({
2979
3142
  type: "string"
2980
3143
  },
2981
3144
  {
2982
- internalType: "uint256",
2983
- name: "schemaId",
2984
- type: "uint256"
2985
- }
2986
- ],
2987
- name: "addFileWithSchema",
2988
- outputs: [
2989
- {
2990
- internalType: "uint256",
2991
- name: "",
2992
- type: "uint256"
2993
- }
2994
- ],
2995
- stateMutability: "nonpayable",
2996
- type: "function"
2997
- },
2998
- {
2999
- inputs: [
3000
- {
3001
- internalType: "uint256",
3002
- name: "fileId",
3003
- type: "uint256"
3145
+ internalType: "address",
3146
+ name: "ownerAddress",
3147
+ type: "address"
3004
3148
  },
3005
3149
  {
3006
3150
  components: [
3007
3151
  {
3008
- internalType: "bytes",
3009
- name: "signature",
3010
- type: "bytes"
3152
+ internalType: "address",
3153
+ name: "account",
3154
+ type: "address"
3011
3155
  },
3012
3156
  {
3013
- components: [
3014
- {
3015
- internalType: "uint256",
3016
- name: "score",
3017
- type: "uint256"
3018
- },
3019
- {
3020
- internalType: "uint256",
3021
- name: "dlpId",
3022
- type: "uint256"
3023
- },
3024
- {
3025
- internalType: "string",
3026
- name: "metadata",
3027
- type: "string"
3028
- },
3029
- {
3030
- internalType: "string",
3031
- name: "proofUrl",
3032
- type: "string"
3033
- },
3034
- {
3035
- internalType: "string",
3036
- name: "instruction",
3037
- type: "string"
3038
- }
3039
- ],
3040
- internalType: "struct IDataRegistry.ProofData",
3041
- name: "data",
3042
- type: "tuple"
3157
+ internalType: "string",
3158
+ name: "key",
3159
+ type: "string"
3043
3160
  }
3044
3161
  ],
3045
- internalType: "struct IDataRegistry.Proof",
3046
- name: "proof",
3047
- type: "tuple"
3048
- }
3049
- ],
3050
- name: "addProof",
3051
- outputs: [],
3052
- stateMutability: "nonpayable",
3053
- type: "function"
3054
- },
3055
- {
3056
- inputs: [
3057
- {
3058
- internalType: "uint256",
3059
- name: "fileId",
3060
- type: "uint256"
3162
+ internalType: "struct IDataRegistry.Permission[]",
3163
+ name: "permissions",
3164
+ type: "tuple[]"
3061
3165
  },
3062
3166
  {
3063
3167
  internalType: "uint256",
3064
- name: "refinerId",
3168
+ name: "schemaId",
3065
3169
  type: "uint256"
3066
- },
3067
- {
3068
- internalType: "string",
3069
- name: "url",
3070
- type: "string"
3071
- },
3072
- {
3073
- internalType: "address",
3074
- name: "account",
3075
- type: "address"
3076
- },
3077
- {
3078
- internalType: "string",
3079
- name: "key",
3080
- type: "string"
3081
3170
  }
3082
3171
  ],
3083
- name: "addRefinementWithPermission",
3084
- outputs: [],
3085
- stateMutability: "nonpayable",
3086
- type: "function"
3087
- },
3088
- {
3089
- inputs: [],
3090
- name: "dataRefinerRegistry",
3091
- outputs: [
3092
- {
3093
- internalType: "contract IDataRefinerRegistry",
3094
- name: "",
3095
- type: "address"
3096
- }
3097
- ],
3098
- stateMutability: "view",
3099
- type: "function"
3100
- },
3101
- {
3102
- inputs: [],
3103
- name: "emitLegacyEvents",
3172
+ name: "addFileWithPermissionsAndSchema",
3104
3173
  outputs: [
3105
3174
  {
3106
- internalType: "bool",
3175
+ internalType: "uint256",
3107
3176
  name: "",
3108
- type: "bool"
3177
+ type: "uint256"
3109
3178
  }
3110
3179
  ],
3111
- stateMutability: "view",
3180
+ stateMutability: "nonpayable",
3112
3181
  type: "function"
3113
3182
  },
3114
3183
  {
@@ -3117,41 +3186,22 @@ var init_DataRegistryImplementation = __esm({
3117
3186
  internalType: "string",
3118
3187
  name: "url",
3119
3188
  type: "string"
3120
- }
3121
- ],
3122
- name: "fileIdByUrl",
3123
- outputs: [
3189
+ },
3124
3190
  {
3125
3191
  internalType: "uint256",
3126
- name: "",
3192
+ name: "schemaId",
3127
3193
  type: "uint256"
3128
3194
  }
3129
3195
  ],
3130
- stateMutability: "view",
3131
- type: "function"
3132
- },
3133
- {
3134
- inputs: [
3135
- {
3136
- internalType: "uint256",
3137
- name: "fileId",
3138
- type: "uint256"
3139
- },
3140
- {
3141
- internalType: "address",
3142
- name: "account",
3143
- type: "address"
3144
- }
3145
- ],
3146
- name: "filePermissions",
3196
+ name: "addFileWithSchema",
3147
3197
  outputs: [
3148
3198
  {
3149
- internalType: "string",
3199
+ internalType: "uint256",
3150
3200
  name: "",
3151
- type: "string"
3201
+ type: "uint256"
3152
3202
  }
3153
3203
  ],
3154
- stateMutability: "view",
3204
+ stateMutability: "nonpayable",
3155
3205
  type: "function"
3156
3206
  },
3157
3207
  {
@@ -3161,14 +3211,173 @@ var init_DataRegistryImplementation = __esm({
3161
3211
  name: "fileId",
3162
3212
  type: "uint256"
3163
3213
  },
3164
- {
3165
- internalType: "uint256",
3166
- name: "index",
3167
- type: "uint256"
3168
- }
3169
- ],
3170
- name: "fileProofs",
3171
- outputs: [
3214
+ {
3215
+ components: [
3216
+ {
3217
+ internalType: "bytes",
3218
+ name: "signature",
3219
+ type: "bytes"
3220
+ },
3221
+ {
3222
+ components: [
3223
+ {
3224
+ internalType: "uint256",
3225
+ name: "score",
3226
+ type: "uint256"
3227
+ },
3228
+ {
3229
+ internalType: "uint256",
3230
+ name: "dlpId",
3231
+ type: "uint256"
3232
+ },
3233
+ {
3234
+ internalType: "string",
3235
+ name: "metadata",
3236
+ type: "string"
3237
+ },
3238
+ {
3239
+ internalType: "string",
3240
+ name: "proofUrl",
3241
+ type: "string"
3242
+ },
3243
+ {
3244
+ internalType: "string",
3245
+ name: "instruction",
3246
+ type: "string"
3247
+ }
3248
+ ],
3249
+ internalType: "struct IDataRegistry.ProofData",
3250
+ name: "data",
3251
+ type: "tuple"
3252
+ }
3253
+ ],
3254
+ internalType: "struct IDataRegistry.Proof",
3255
+ name: "proof",
3256
+ type: "tuple"
3257
+ }
3258
+ ],
3259
+ name: "addProof",
3260
+ outputs: [],
3261
+ stateMutability: "nonpayable",
3262
+ type: "function"
3263
+ },
3264
+ {
3265
+ inputs: [
3266
+ {
3267
+ internalType: "uint256",
3268
+ name: "fileId",
3269
+ type: "uint256"
3270
+ },
3271
+ {
3272
+ internalType: "uint256",
3273
+ name: "refinerId",
3274
+ type: "uint256"
3275
+ },
3276
+ {
3277
+ internalType: "string",
3278
+ name: "url",
3279
+ type: "string"
3280
+ },
3281
+ {
3282
+ internalType: "address",
3283
+ name: "account",
3284
+ type: "address"
3285
+ },
3286
+ {
3287
+ internalType: "string",
3288
+ name: "key",
3289
+ type: "string"
3290
+ }
3291
+ ],
3292
+ name: "addRefinementWithPermission",
3293
+ outputs: [],
3294
+ stateMutability: "nonpayable",
3295
+ type: "function"
3296
+ },
3297
+ {
3298
+ inputs: [],
3299
+ name: "dataRefinerRegistry",
3300
+ outputs: [
3301
+ {
3302
+ internalType: "contract IDataRefinerRegistry",
3303
+ name: "",
3304
+ type: "address"
3305
+ }
3306
+ ],
3307
+ stateMutability: "view",
3308
+ type: "function"
3309
+ },
3310
+ {
3311
+ inputs: [],
3312
+ name: "emitLegacyEvents",
3313
+ outputs: [
3314
+ {
3315
+ internalType: "bool",
3316
+ name: "",
3317
+ type: "bool"
3318
+ }
3319
+ ],
3320
+ stateMutability: "view",
3321
+ type: "function"
3322
+ },
3323
+ {
3324
+ inputs: [
3325
+ {
3326
+ internalType: "string",
3327
+ name: "url",
3328
+ type: "string"
3329
+ }
3330
+ ],
3331
+ name: "fileIdByUrl",
3332
+ outputs: [
3333
+ {
3334
+ internalType: "uint256",
3335
+ name: "",
3336
+ type: "uint256"
3337
+ }
3338
+ ],
3339
+ stateMutability: "view",
3340
+ type: "function"
3341
+ },
3342
+ {
3343
+ inputs: [
3344
+ {
3345
+ internalType: "uint256",
3346
+ name: "fileId",
3347
+ type: "uint256"
3348
+ },
3349
+ {
3350
+ internalType: "address",
3351
+ name: "account",
3352
+ type: "address"
3353
+ }
3354
+ ],
3355
+ name: "filePermissions",
3356
+ outputs: [
3357
+ {
3358
+ internalType: "string",
3359
+ name: "",
3360
+ type: "string"
3361
+ }
3362
+ ],
3363
+ stateMutability: "view",
3364
+ type: "function"
3365
+ },
3366
+ {
3367
+ inputs: [
3368
+ {
3369
+ internalType: "uint256",
3370
+ name: "fileId",
3371
+ type: "uint256"
3372
+ },
3373
+ {
3374
+ internalType: "uint256",
3375
+ name: "index",
3376
+ type: "uint256"
3377
+ }
3378
+ ],
3379
+ name: "fileProofs",
3380
+ outputs: [
3172
3381
  {
3173
3382
  components: [
3174
3383
  {
@@ -35861,110 +36070,644 @@ var init_transactionHandle = __esm({
35861
36070
  }
35862
36071
  });
35863
36072
 
35864
- // src/utils/ipfs.ts
35865
- var ipfs_exports = {};
35866
- __export(ipfs_exports, {
35867
- DEFAULT_IPFS_GATEWAY: () => DEFAULT_IPFS_GATEWAY,
35868
- IPFS_GATEWAYS: () => IPFS_GATEWAYS,
35869
- convertIpfsUrl: () => convertIpfsUrl,
35870
- convertIpfsUrlWithFallbacks: () => convertIpfsUrlWithFallbacks,
35871
- extractIpfsHash: () => extractIpfsHash,
35872
- fetchWithFallbacks: () => fetchWithFallbacks,
35873
- getGatewayUrls: () => getGatewayUrls,
35874
- isIpfsUrl: () => isIpfsUrl
35875
- });
35876
- function isIpfsUrl(url) {
35877
- return url.startsWith("ipfs://");
35878
- }
35879
- function convertIpfsUrl(url, gateway = DEFAULT_IPFS_GATEWAY) {
35880
- if (isIpfsUrl(url)) {
35881
- const hash = url.replace("ipfs://", "");
35882
- return `${gateway}${hash}`;
35883
- }
35884
- return url;
35885
- }
35886
- function extractIpfsHash(url) {
35887
- const patterns = [
35888
- /ipfs\/([a-zA-Z0-9]+)/,
35889
- // https://gateway.pinata.cloud/ipfs/HASH
35890
- /^ipfs:\/\/([a-zA-Z0-9]+)$/,
35891
- // ipfs://HASH
35892
- /^([a-zA-Z0-9]{46,})$/
35893
- // Just the hash (46+ chars for IPFS hashes)
35894
- ];
35895
- for (const pattern of patterns) {
35896
- const match = url.match(pattern);
35897
- if (match) {
35898
- return match[1];
35899
- }
35900
- }
35901
- return null;
35902
- }
35903
- function getGatewayUrls(hash) {
35904
- return IPFS_GATEWAYS.map((gateway) => `${gateway}${hash}`);
35905
- }
35906
- function convertIpfsUrlWithFallbacks(url) {
35907
- const hash = extractIpfsHash(url);
35908
- if (hash) {
35909
- return getGatewayUrls(hash);
35910
- }
35911
- return [url];
35912
- }
35913
- async function fetchWithFallbacks(url, options) {
35914
- const hash = extractIpfsHash(url);
35915
- if (!hash) {
35916
- return fetch(url, options);
35917
- }
35918
- const gatewayUrls = getGatewayUrls(hash);
35919
- let lastError = null;
35920
- for (let i = 0; i < gatewayUrls.length; i++) {
35921
- const gatewayUrl = gatewayUrls[i];
35922
- try {
35923
- const response = await fetch(gatewayUrl, {
35924
- ...options,
35925
- // Add timeout to avoid hanging on slow gateways
35926
- signal: AbortSignal.timeout(1e4)
35927
- // 10 second timeout
35928
- });
35929
- if (response.ok) {
35930
- return response;
35931
- }
35932
- if (response.status === 429) {
35933
- lastError = new Error(`Gateway rate limited: ${gatewayUrl}`);
35934
- continue;
35935
- }
35936
- lastError = new Error(`Gateway error ${response.status}: ${gatewayUrl}`);
35937
- } catch (error) {
35938
- lastError = error instanceof Error ? error : new Error(String(error));
35939
- if (lastError.message.includes("429") || lastError.name === "TimeoutError") {
35940
- continue;
35941
- }
35942
- }
35943
- if (i < gatewayUrls.length - 1) {
35944
- await new Promise((resolve) => setTimeout(resolve, 1e3 * (i + 1)));
35945
- }
35946
- }
35947
- throw new Error(
35948
- `All IPFS gateways failed for hash ${hash}. Last error: ${lastError?.message}`
35949
- );
35950
- }
35951
- var DEFAULT_IPFS_GATEWAY, IPFS_GATEWAYS;
35952
- var init_ipfs = __esm({
35953
- "src/utils/ipfs.ts"() {
36073
+ // src/generated/subgraph.ts
36074
+ var GetUserPermissionsDocument, GetUserTrustedServersDocument, GetUserFilesDocument, GetFileProofsDocument, GetDlpDocument, GetSchemaDocument, ListSchemasDocument, CountSchemasDocument;
36075
+ var init_subgraph = __esm({
36076
+ "src/generated/subgraph.ts"() {
35954
36077
  "use strict";
35955
- DEFAULT_IPFS_GATEWAY = "https://dweb.link/ipfs/";
35956
- IPFS_GATEWAYS = [
35957
- "https://dweb.link/ipfs/",
35958
- // Interplanetary Shipyard - highly reliable
35959
- "https://ipfs.io/ipfs/",
35960
- // IPFS Foundation - reliable
35961
- "https://cloudflare-ipfs.com/ipfs/",
35962
- // Cloudflare - good performance
35963
- "https://gateway.pinata.cloud/ipfs/",
35964
- // Pinata - backup option (has rate limits)
35965
- "https://ipfs.filebase.io/ipfs/"
35966
- // Filebase - emerging reliable option
35967
- ];
36078
+ GetUserPermissionsDocument = {
36079
+ kind: "Document",
36080
+ definitions: [
36081
+ {
36082
+ kind: "OperationDefinition",
36083
+ operation: "query",
36084
+ name: { kind: "Name", value: "GetUserPermissions" },
36085
+ variableDefinitions: [
36086
+ {
36087
+ kind: "VariableDefinition",
36088
+ variable: {
36089
+ kind: "Variable",
36090
+ name: { kind: "Name", value: "userId" }
36091
+ },
36092
+ type: {
36093
+ kind: "NonNullType",
36094
+ type: { kind: "NamedType", name: { kind: "Name", value: "ID" } }
36095
+ }
36096
+ }
36097
+ ],
36098
+ selectionSet: {
36099
+ kind: "SelectionSet",
36100
+ selections: [
36101
+ {
36102
+ kind: "Field",
36103
+ name: { kind: "Name", value: "user" },
36104
+ arguments: [
36105
+ {
36106
+ kind: "Argument",
36107
+ name: { kind: "Name", value: "id" },
36108
+ value: {
36109
+ kind: "Variable",
36110
+ name: { kind: "Name", value: "userId" }
36111
+ }
36112
+ }
36113
+ ],
36114
+ selectionSet: {
36115
+ kind: "SelectionSet",
36116
+ selections: [
36117
+ { kind: "Field", name: { kind: "Name", value: "id" } },
36118
+ {
36119
+ kind: "Field",
36120
+ name: { kind: "Name", value: "permissions" },
36121
+ selectionSet: {
36122
+ kind: "SelectionSet",
36123
+ selections: [
36124
+ { kind: "Field", name: { kind: "Name", value: "id" } },
36125
+ { kind: "Field", name: { kind: "Name", value: "grant" } },
36126
+ { kind: "Field", name: { kind: "Name", value: "nonce" } },
36127
+ {
36128
+ kind: "Field",
36129
+ name: { kind: "Name", value: "signature" }
36130
+ },
36131
+ {
36132
+ kind: "Field",
36133
+ name: { kind: "Name", value: "startBlock" }
36134
+ },
36135
+ {
36136
+ kind: "Field",
36137
+ name: { kind: "Name", value: "endBlock" }
36138
+ },
36139
+ {
36140
+ kind: "Field",
36141
+ name: { kind: "Name", value: "addedAtBlock" }
36142
+ },
36143
+ {
36144
+ kind: "Field",
36145
+ name: { kind: "Name", value: "addedAtTimestamp" }
36146
+ },
36147
+ {
36148
+ kind: "Field",
36149
+ name: { kind: "Name", value: "transactionHash" }
36150
+ },
36151
+ {
36152
+ kind: "Field",
36153
+ name: { kind: "Name", value: "grantee" },
36154
+ selectionSet: {
36155
+ kind: "SelectionSet",
36156
+ selections: [
36157
+ {
36158
+ kind: "Field",
36159
+ name: { kind: "Name", value: "id" }
36160
+ },
36161
+ {
36162
+ kind: "Field",
36163
+ name: { kind: "Name", value: "address" }
36164
+ }
36165
+ ]
36166
+ }
36167
+ },
36168
+ {
36169
+ kind: "Field",
36170
+ name: { kind: "Name", value: "filePermissions" },
36171
+ selectionSet: {
36172
+ kind: "SelectionSet",
36173
+ selections: [
36174
+ {
36175
+ kind: "Field",
36176
+ name: { kind: "Name", value: "file" },
36177
+ selectionSet: {
36178
+ kind: "SelectionSet",
36179
+ selections: [
36180
+ {
36181
+ kind: "Field",
36182
+ name: { kind: "Name", value: "id" }
36183
+ },
36184
+ {
36185
+ kind: "Field",
36186
+ name: { kind: "Name", value: "url" }
36187
+ }
36188
+ ]
36189
+ }
36190
+ }
36191
+ ]
36192
+ }
36193
+ }
36194
+ ]
36195
+ }
36196
+ }
36197
+ ]
36198
+ }
36199
+ }
36200
+ ]
36201
+ }
36202
+ }
36203
+ ]
36204
+ };
36205
+ GetUserTrustedServersDocument = {
36206
+ kind: "Document",
36207
+ definitions: [
36208
+ {
36209
+ kind: "OperationDefinition",
36210
+ operation: "query",
36211
+ name: { kind: "Name", value: "GetUserTrustedServers" },
36212
+ variableDefinitions: [
36213
+ {
36214
+ kind: "VariableDefinition",
36215
+ variable: {
36216
+ kind: "Variable",
36217
+ name: { kind: "Name", value: "userId" }
36218
+ },
36219
+ type: {
36220
+ kind: "NonNullType",
36221
+ type: { kind: "NamedType", name: { kind: "Name", value: "ID" } }
36222
+ }
36223
+ }
36224
+ ],
36225
+ selectionSet: {
36226
+ kind: "SelectionSet",
36227
+ selections: [
36228
+ {
36229
+ kind: "Field",
36230
+ name: { kind: "Name", value: "user" },
36231
+ arguments: [
36232
+ {
36233
+ kind: "Argument",
36234
+ name: { kind: "Name", value: "id" },
36235
+ value: {
36236
+ kind: "Variable",
36237
+ name: { kind: "Name", value: "userId" }
36238
+ }
36239
+ }
36240
+ ],
36241
+ selectionSet: {
36242
+ kind: "SelectionSet",
36243
+ selections: [
36244
+ { kind: "Field", name: { kind: "Name", value: "id" } },
36245
+ {
36246
+ kind: "Field",
36247
+ name: { kind: "Name", value: "serverTrusts" },
36248
+ selectionSet: {
36249
+ kind: "SelectionSet",
36250
+ selections: [
36251
+ { kind: "Field", name: { kind: "Name", value: "id" } },
36252
+ {
36253
+ kind: "Field",
36254
+ name: { kind: "Name", value: "server" },
36255
+ selectionSet: {
36256
+ kind: "SelectionSet",
36257
+ selections: [
36258
+ {
36259
+ kind: "Field",
36260
+ name: { kind: "Name", value: "id" }
36261
+ },
36262
+ {
36263
+ kind: "Field",
36264
+ name: { kind: "Name", value: "serverAddress" }
36265
+ },
36266
+ {
36267
+ kind: "Field",
36268
+ name: { kind: "Name", value: "url" }
36269
+ },
36270
+ {
36271
+ kind: "Field",
36272
+ name: { kind: "Name", value: "publicKey" }
36273
+ }
36274
+ ]
36275
+ }
36276
+ },
36277
+ {
36278
+ kind: "Field",
36279
+ name: { kind: "Name", value: "trustedAt" }
36280
+ },
36281
+ {
36282
+ kind: "Field",
36283
+ name: { kind: "Name", value: "trustedAtBlock" }
36284
+ },
36285
+ {
36286
+ kind: "Field",
36287
+ name: { kind: "Name", value: "untrustedAtBlock" }
36288
+ },
36289
+ {
36290
+ kind: "Field",
36291
+ name: { kind: "Name", value: "transactionHash" }
36292
+ }
36293
+ ]
36294
+ }
36295
+ }
36296
+ ]
36297
+ }
36298
+ }
36299
+ ]
36300
+ }
36301
+ }
36302
+ ]
36303
+ };
36304
+ GetUserFilesDocument = {
36305
+ kind: "Document",
36306
+ definitions: [
36307
+ {
36308
+ kind: "OperationDefinition",
36309
+ operation: "query",
36310
+ name: { kind: "Name", value: "GetUserFiles" },
36311
+ variableDefinitions: [
36312
+ {
36313
+ kind: "VariableDefinition",
36314
+ variable: {
36315
+ kind: "Variable",
36316
+ name: { kind: "Name", value: "userId" }
36317
+ },
36318
+ type: {
36319
+ kind: "NonNullType",
36320
+ type: { kind: "NamedType", name: { kind: "Name", value: "ID" } }
36321
+ }
36322
+ }
36323
+ ],
36324
+ selectionSet: {
36325
+ kind: "SelectionSet",
36326
+ selections: [
36327
+ {
36328
+ kind: "Field",
36329
+ name: { kind: "Name", value: "user" },
36330
+ arguments: [
36331
+ {
36332
+ kind: "Argument",
36333
+ name: { kind: "Name", value: "id" },
36334
+ value: {
36335
+ kind: "Variable",
36336
+ name: { kind: "Name", value: "userId" }
36337
+ }
36338
+ }
36339
+ ],
36340
+ selectionSet: {
36341
+ kind: "SelectionSet",
36342
+ selections: [
36343
+ { kind: "Field", name: { kind: "Name", value: "id" } },
36344
+ {
36345
+ kind: "Field",
36346
+ name: { kind: "Name", value: "files" },
36347
+ selectionSet: {
36348
+ kind: "SelectionSet",
36349
+ selections: [
36350
+ { kind: "Field", name: { kind: "Name", value: "id" } },
36351
+ { kind: "Field", name: { kind: "Name", value: "url" } },
36352
+ {
36353
+ kind: "Field",
36354
+ name: { kind: "Name", value: "schemaId" }
36355
+ },
36356
+ {
36357
+ kind: "Field",
36358
+ name: { kind: "Name", value: "addedAtBlock" }
36359
+ },
36360
+ {
36361
+ kind: "Field",
36362
+ name: { kind: "Name", value: "addedAtTimestamp" }
36363
+ },
36364
+ {
36365
+ kind: "Field",
36366
+ name: { kind: "Name", value: "transactionHash" }
36367
+ },
36368
+ {
36369
+ kind: "Field",
36370
+ name: { kind: "Name", value: "owner" },
36371
+ selectionSet: {
36372
+ kind: "SelectionSet",
36373
+ selections: [
36374
+ {
36375
+ kind: "Field",
36376
+ name: { kind: "Name", value: "id" }
36377
+ }
36378
+ ]
36379
+ }
36380
+ }
36381
+ ]
36382
+ }
36383
+ }
36384
+ ]
36385
+ }
36386
+ }
36387
+ ]
36388
+ }
36389
+ }
36390
+ ]
36391
+ };
36392
+ GetFileProofsDocument = {
36393
+ kind: "Document",
36394
+ definitions: [
36395
+ {
36396
+ kind: "OperationDefinition",
36397
+ operation: "query",
36398
+ name: { kind: "Name", value: "GetFileProofs" },
36399
+ variableDefinitions: [
36400
+ {
36401
+ kind: "VariableDefinition",
36402
+ variable: {
36403
+ kind: "Variable",
36404
+ name: { kind: "Name", value: "fileIds" }
36405
+ },
36406
+ type: {
36407
+ kind: "NonNullType",
36408
+ type: {
36409
+ kind: "ListType",
36410
+ type: {
36411
+ kind: "NonNullType",
36412
+ type: {
36413
+ kind: "NamedType",
36414
+ name: { kind: "Name", value: "BigInt" }
36415
+ }
36416
+ }
36417
+ }
36418
+ }
36419
+ }
36420
+ ],
36421
+ selectionSet: {
36422
+ kind: "SelectionSet",
36423
+ selections: [
36424
+ {
36425
+ kind: "Field",
36426
+ name: { kind: "Name", value: "dataRegistryProofs" },
36427
+ arguments: [
36428
+ {
36429
+ kind: "Argument",
36430
+ name: { kind: "Name", value: "where" },
36431
+ value: {
36432
+ kind: "ObjectValue",
36433
+ fields: [
36434
+ {
36435
+ kind: "ObjectField",
36436
+ name: { kind: "Name", value: "fileId_in" },
36437
+ value: {
36438
+ kind: "Variable",
36439
+ name: { kind: "Name", value: "fileIds" }
36440
+ }
36441
+ }
36442
+ ]
36443
+ }
36444
+ }
36445
+ ],
36446
+ selectionSet: {
36447
+ kind: "SelectionSet",
36448
+ selections: [
36449
+ { kind: "Field", name: { kind: "Name", value: "fileId" } },
36450
+ {
36451
+ kind: "Field",
36452
+ name: { kind: "Name", value: "dlp" },
36453
+ selectionSet: {
36454
+ kind: "SelectionSet",
36455
+ selections: [
36456
+ { kind: "Field", name: { kind: "Name", value: "id" } }
36457
+ ]
36458
+ }
36459
+ }
36460
+ ]
36461
+ }
36462
+ }
36463
+ ]
36464
+ }
36465
+ }
36466
+ ]
36467
+ };
36468
+ GetDlpDocument = {
36469
+ kind: "Document",
36470
+ definitions: [
36471
+ {
36472
+ kind: "OperationDefinition",
36473
+ operation: "query",
36474
+ name: { kind: "Name", value: "GetDLP" },
36475
+ variableDefinitions: [
36476
+ {
36477
+ kind: "VariableDefinition",
36478
+ variable: { kind: "Variable", name: { kind: "Name", value: "id" } },
36479
+ type: {
36480
+ kind: "NonNullType",
36481
+ type: { kind: "NamedType", name: { kind: "Name", value: "ID" } }
36482
+ }
36483
+ }
36484
+ ],
36485
+ selectionSet: {
36486
+ kind: "SelectionSet",
36487
+ selections: [
36488
+ {
36489
+ kind: "Field",
36490
+ name: { kind: "Name", value: "dlp" },
36491
+ arguments: [
36492
+ {
36493
+ kind: "Argument",
36494
+ name: { kind: "Name", value: "id" },
36495
+ value: {
36496
+ kind: "Variable",
36497
+ name: { kind: "Name", value: "id" }
36498
+ }
36499
+ }
36500
+ ],
36501
+ selectionSet: {
36502
+ kind: "SelectionSet",
36503
+ selections: [
36504
+ { kind: "Field", name: { kind: "Name", value: "id" } },
36505
+ { kind: "Field", name: { kind: "Name", value: "name" } },
36506
+ { kind: "Field", name: { kind: "Name", value: "metadata" } },
36507
+ { kind: "Field", name: { kind: "Name", value: "status" } },
36508
+ { kind: "Field", name: { kind: "Name", value: "address" } },
36509
+ { kind: "Field", name: { kind: "Name", value: "owner" } }
36510
+ ]
36511
+ }
36512
+ }
36513
+ ]
36514
+ }
36515
+ }
36516
+ ]
36517
+ };
36518
+ GetSchemaDocument = {
36519
+ kind: "Document",
36520
+ definitions: [
36521
+ {
36522
+ kind: "OperationDefinition",
36523
+ operation: "query",
36524
+ name: { kind: "Name", value: "GetSchema" },
36525
+ variableDefinitions: [
36526
+ {
36527
+ kind: "VariableDefinition",
36528
+ variable: { kind: "Variable", name: { kind: "Name", value: "id" } },
36529
+ type: {
36530
+ kind: "NonNullType",
36531
+ type: { kind: "NamedType", name: { kind: "Name", value: "ID" } }
36532
+ }
36533
+ }
36534
+ ],
36535
+ selectionSet: {
36536
+ kind: "SelectionSet",
36537
+ selections: [
36538
+ {
36539
+ kind: "Field",
36540
+ name: { kind: "Name", value: "schema" },
36541
+ arguments: [
36542
+ {
36543
+ kind: "Argument",
36544
+ name: { kind: "Name", value: "id" },
36545
+ value: {
36546
+ kind: "Variable",
36547
+ name: { kind: "Name", value: "id" }
36548
+ }
36549
+ }
36550
+ ],
36551
+ selectionSet: {
36552
+ kind: "SelectionSet",
36553
+ selections: [
36554
+ { kind: "Field", name: { kind: "Name", value: "id" } },
36555
+ { kind: "Field", name: { kind: "Name", value: "name" } },
36556
+ { kind: "Field", name: { kind: "Name", value: "dialect" } },
36557
+ {
36558
+ kind: "Field",
36559
+ name: { kind: "Name", value: "definitionUrl" }
36560
+ },
36561
+ { kind: "Field", name: { kind: "Name", value: "createdAt" } },
36562
+ {
36563
+ kind: "Field",
36564
+ name: { kind: "Name", value: "createdAtBlock" }
36565
+ },
36566
+ {
36567
+ kind: "Field",
36568
+ name: { kind: "Name", value: "createdTxHash" }
36569
+ },
36570
+ {
36571
+ kind: "Field",
36572
+ name: { kind: "Name", value: "refiners" },
36573
+ selectionSet: {
36574
+ kind: "SelectionSet",
36575
+ selections: [
36576
+ { kind: "Field", name: { kind: "Name", value: "id" } },
36577
+ { kind: "Field", name: { kind: "Name", value: "name" } },
36578
+ { kind: "Field", name: { kind: "Name", value: "owner" } }
36579
+ ]
36580
+ }
36581
+ }
36582
+ ]
36583
+ }
36584
+ }
36585
+ ]
36586
+ }
36587
+ }
36588
+ ]
36589
+ };
36590
+ ListSchemasDocument = {
36591
+ kind: "Document",
36592
+ definitions: [
36593
+ {
36594
+ kind: "OperationDefinition",
36595
+ operation: "query",
36596
+ name: { kind: "Name", value: "ListSchemas" },
36597
+ variableDefinitions: [
36598
+ {
36599
+ kind: "VariableDefinition",
36600
+ variable: {
36601
+ kind: "Variable",
36602
+ name: { kind: "Name", value: "first" }
36603
+ },
36604
+ type: {
36605
+ kind: "NonNullType",
36606
+ type: { kind: "NamedType", name: { kind: "Name", value: "Int" } }
36607
+ }
36608
+ },
36609
+ {
36610
+ kind: "VariableDefinition",
36611
+ variable: { kind: "Variable", name: { kind: "Name", value: "skip" } },
36612
+ type: {
36613
+ kind: "NonNullType",
36614
+ type: { kind: "NamedType", name: { kind: "Name", value: "Int" } }
36615
+ }
36616
+ }
36617
+ ],
36618
+ selectionSet: {
36619
+ kind: "SelectionSet",
36620
+ selections: [
36621
+ {
36622
+ kind: "Field",
36623
+ name: { kind: "Name", value: "schemas" },
36624
+ arguments: [
36625
+ {
36626
+ kind: "Argument",
36627
+ name: { kind: "Name", value: "first" },
36628
+ value: {
36629
+ kind: "Variable",
36630
+ name: { kind: "Name", value: "first" }
36631
+ }
36632
+ },
36633
+ {
36634
+ kind: "Argument",
36635
+ name: { kind: "Name", value: "skip" },
36636
+ value: {
36637
+ kind: "Variable",
36638
+ name: { kind: "Name", value: "skip" }
36639
+ }
36640
+ },
36641
+ {
36642
+ kind: "Argument",
36643
+ name: { kind: "Name", value: "orderBy" },
36644
+ value: { kind: "EnumValue", value: "createdAt" }
36645
+ },
36646
+ {
36647
+ kind: "Argument",
36648
+ name: { kind: "Name", value: "orderDirection" },
36649
+ value: { kind: "EnumValue", value: "desc" }
36650
+ }
36651
+ ],
36652
+ selectionSet: {
36653
+ kind: "SelectionSet",
36654
+ selections: [
36655
+ { kind: "Field", name: { kind: "Name", value: "id" } },
36656
+ { kind: "Field", name: { kind: "Name", value: "name" } },
36657
+ { kind: "Field", name: { kind: "Name", value: "dialect" } },
36658
+ {
36659
+ kind: "Field",
36660
+ name: { kind: "Name", value: "definitionUrl" }
36661
+ },
36662
+ { kind: "Field", name: { kind: "Name", value: "createdAt" } },
36663
+ {
36664
+ kind: "Field",
36665
+ name: { kind: "Name", value: "createdAtBlock" }
36666
+ },
36667
+ {
36668
+ kind: "Field",
36669
+ name: { kind: "Name", value: "createdTxHash" }
36670
+ }
36671
+ ]
36672
+ }
36673
+ }
36674
+ ]
36675
+ }
36676
+ }
36677
+ ]
36678
+ };
36679
+ CountSchemasDocument = {
36680
+ kind: "Document",
36681
+ definitions: [
36682
+ {
36683
+ kind: "OperationDefinition",
36684
+ operation: "query",
36685
+ name: { kind: "Name", value: "CountSchemas" },
36686
+ selectionSet: {
36687
+ kind: "SelectionSet",
36688
+ selections: [
36689
+ {
36690
+ kind: "Field",
36691
+ name: { kind: "Name", value: "schemas" },
36692
+ arguments: [
36693
+ {
36694
+ kind: "Argument",
36695
+ name: { kind: "Name", value: "first" },
36696
+ value: { kind: "IntValue", value: "1000" }
36697
+ }
36698
+ ],
36699
+ selectionSet: {
36700
+ kind: "SelectionSet",
36701
+ selections: [
36702
+ { kind: "Field", name: { kind: "Name", value: "id" } }
36703
+ ]
36704
+ }
36705
+ }
36706
+ ]
36707
+ }
36708
+ }
36709
+ ]
36710
+ };
35968
36711
  }
35969
36712
  });
35970
36713
 
@@ -36026,212 +36769,10 @@ var init_registry = __esm({
36026
36769
  }
36027
36770
  });
36028
36771
 
36029
- // src/generated/subgraph.ts
36030
- var GetSchemaDocument, ListSchemasDocument, CountSchemasDocument;
36031
- var init_subgraph = __esm({
36032
- "src/generated/subgraph.ts"() {
36033
- "use strict";
36034
- GetSchemaDocument = {
36035
- kind: "Document",
36036
- definitions: [
36037
- {
36038
- kind: "OperationDefinition",
36039
- operation: "query",
36040
- name: { kind: "Name", value: "GetSchema" },
36041
- variableDefinitions: [
36042
- {
36043
- kind: "VariableDefinition",
36044
- variable: { kind: "Variable", name: { kind: "Name", value: "id" } },
36045
- type: {
36046
- kind: "NonNullType",
36047
- type: { kind: "NamedType", name: { kind: "Name", value: "ID" } }
36048
- }
36049
- }
36050
- ],
36051
- selectionSet: {
36052
- kind: "SelectionSet",
36053
- selections: [
36054
- {
36055
- kind: "Field",
36056
- name: { kind: "Name", value: "schema" },
36057
- arguments: [
36058
- {
36059
- kind: "Argument",
36060
- name: { kind: "Name", value: "id" },
36061
- value: {
36062
- kind: "Variable",
36063
- name: { kind: "Name", value: "id" }
36064
- }
36065
- }
36066
- ],
36067
- selectionSet: {
36068
- kind: "SelectionSet",
36069
- selections: [
36070
- { kind: "Field", name: { kind: "Name", value: "id" } },
36071
- { kind: "Field", name: { kind: "Name", value: "name" } },
36072
- { kind: "Field", name: { kind: "Name", value: "dialect" } },
36073
- {
36074
- kind: "Field",
36075
- name: { kind: "Name", value: "definitionUrl" }
36076
- },
36077
- { kind: "Field", name: { kind: "Name", value: "createdAt" } },
36078
- {
36079
- kind: "Field",
36080
- name: { kind: "Name", value: "createdAtBlock" }
36081
- },
36082
- {
36083
- kind: "Field",
36084
- name: { kind: "Name", value: "createdTxHash" }
36085
- },
36086
- {
36087
- kind: "Field",
36088
- name: { kind: "Name", value: "refiners" },
36089
- selectionSet: {
36090
- kind: "SelectionSet",
36091
- selections: [
36092
- { kind: "Field", name: { kind: "Name", value: "id" } },
36093
- { kind: "Field", name: { kind: "Name", value: "name" } },
36094
- { kind: "Field", name: { kind: "Name", value: "owner" } }
36095
- ]
36096
- }
36097
- }
36098
- ]
36099
- }
36100
- }
36101
- ]
36102
- }
36103
- }
36104
- ]
36105
- };
36106
- ListSchemasDocument = {
36107
- kind: "Document",
36108
- definitions: [
36109
- {
36110
- kind: "OperationDefinition",
36111
- operation: "query",
36112
- name: { kind: "Name", value: "ListSchemas" },
36113
- variableDefinitions: [
36114
- {
36115
- kind: "VariableDefinition",
36116
- variable: {
36117
- kind: "Variable",
36118
- name: { kind: "Name", value: "first" }
36119
- },
36120
- type: {
36121
- kind: "NonNullType",
36122
- type: { kind: "NamedType", name: { kind: "Name", value: "Int" } }
36123
- }
36124
- },
36125
- {
36126
- kind: "VariableDefinition",
36127
- variable: { kind: "Variable", name: { kind: "Name", value: "skip" } },
36128
- type: {
36129
- kind: "NonNullType",
36130
- type: { kind: "NamedType", name: { kind: "Name", value: "Int" } }
36131
- }
36132
- }
36133
- ],
36134
- selectionSet: {
36135
- kind: "SelectionSet",
36136
- selections: [
36137
- {
36138
- kind: "Field",
36139
- name: { kind: "Name", value: "schemas" },
36140
- arguments: [
36141
- {
36142
- kind: "Argument",
36143
- name: { kind: "Name", value: "first" },
36144
- value: {
36145
- kind: "Variable",
36146
- name: { kind: "Name", value: "first" }
36147
- }
36148
- },
36149
- {
36150
- kind: "Argument",
36151
- name: { kind: "Name", value: "skip" },
36152
- value: {
36153
- kind: "Variable",
36154
- name: { kind: "Name", value: "skip" }
36155
- }
36156
- },
36157
- {
36158
- kind: "Argument",
36159
- name: { kind: "Name", value: "orderBy" },
36160
- value: { kind: "EnumValue", value: "createdAt" }
36161
- },
36162
- {
36163
- kind: "Argument",
36164
- name: { kind: "Name", value: "orderDirection" },
36165
- value: { kind: "EnumValue", value: "desc" }
36166
- }
36167
- ],
36168
- selectionSet: {
36169
- kind: "SelectionSet",
36170
- selections: [
36171
- { kind: "Field", name: { kind: "Name", value: "id" } },
36172
- { kind: "Field", name: { kind: "Name", value: "name" } },
36173
- { kind: "Field", name: { kind: "Name", value: "dialect" } },
36174
- {
36175
- kind: "Field",
36176
- name: { kind: "Name", value: "definitionUrl" }
36177
- },
36178
- { kind: "Field", name: { kind: "Name", value: "createdAt" } },
36179
- {
36180
- kind: "Field",
36181
- name: { kind: "Name", value: "createdAtBlock" }
36182
- },
36183
- {
36184
- kind: "Field",
36185
- name: { kind: "Name", value: "createdTxHash" }
36186
- }
36187
- ]
36188
- }
36189
- }
36190
- ]
36191
- }
36192
- }
36193
- ]
36194
- };
36195
- CountSchemasDocument = {
36196
- kind: "Document",
36197
- definitions: [
36198
- {
36199
- kind: "OperationDefinition",
36200
- operation: "query",
36201
- name: { kind: "Name", value: "CountSchemas" },
36202
- selectionSet: {
36203
- kind: "SelectionSet",
36204
- selections: [
36205
- {
36206
- kind: "Field",
36207
- name: { kind: "Name", value: "schemas" },
36208
- arguments: [
36209
- {
36210
- kind: "Argument",
36211
- name: { kind: "Name", value: "first" },
36212
- value: { kind: "IntValue", value: "1000" }
36213
- }
36214
- ],
36215
- selectionSet: {
36216
- kind: "SelectionSet",
36217
- selections: [
36218
- { kind: "Field", name: { kind: "Name", value: "id" } }
36219
- ]
36220
- }
36221
- }
36222
- ]
36223
- }
36224
- }
36225
- ]
36226
- };
36227
- }
36228
- });
36229
-
36230
36772
  // src/utils/urlResolver.ts
36231
- async function fetchFromUrl(url) {
36773
+ async function fetchFromUrl(url, downloadRelayer) {
36232
36774
  try {
36233
- const httpUrl = resolveToHttp(url);
36234
- const response = await fetchWithRetry(httpUrl, url);
36775
+ const response = await fetchWithRelayer(url, downloadRelayer);
36235
36776
  if (!response.ok) {
36236
36777
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
36237
36778
  }
@@ -36245,43 +36786,11 @@ async function fetchFromUrl(url) {
36245
36786
  );
36246
36787
  }
36247
36788
  }
36248
- function resolveToHttp(url) {
36249
- if (url.startsWith("ipfs://")) {
36250
- return convertIpfsUrl(url);
36251
- }
36252
- if (url.startsWith("ar://")) {
36253
- const txId = url.replace("ar://", "");
36254
- return `https://arweave.net/${txId}`;
36255
- }
36256
- if (url.startsWith("https://") || url.startsWith("http://")) {
36257
- return url;
36258
- }
36259
- throw new Error(`Unsupported protocol in URL: ${url}`);
36260
- }
36261
- async function fetchWithRetry(httpUrl, originalUrl) {
36262
- try {
36263
- const response = await fetch(httpUrl);
36264
- if (response.ok) return response;
36265
- } catch {
36266
- }
36267
- if (originalUrl.startsWith("ipfs://")) {
36268
- for (const gateway of IPFS_GATEWAYS) {
36269
- try {
36270
- const alternativeUrl = convertIpfsUrl(originalUrl, gateway);
36271
- if (alternativeUrl === httpUrl) continue;
36272
- const response = await fetch(alternativeUrl);
36273
- if (response.ok) return response;
36274
- } catch {
36275
- }
36276
- }
36277
- }
36278
- return fetch(httpUrl);
36279
- }
36280
36789
  var UrlResolutionError;
36281
36790
  var init_urlResolver = __esm({
36282
36791
  "src/utils/urlResolver.ts"() {
36283
36792
  "use strict";
36284
- init_ipfs();
36793
+ init_download();
36285
36794
  UrlResolutionError = class extends Error {
36286
36795
  constructor(message, url, cause) {
36287
36796
  super(message);
@@ -36374,7 +36883,7 @@ var init_schemas = __esm({
36374
36883
  dialect,
36375
36884
  schema: schemaDefinition
36376
36885
  };
36377
- validateDataSchema(dataSchema);
36886
+ validateDataSchemaAgainstMetaSchema(dataSchema);
36378
36887
  if (!this.context.storageManager) {
36379
36888
  if (this.context.validateStorageRequired) {
36380
36889
  this.context.validateStorageRequired();
@@ -36477,13 +36986,16 @@ var init_schemas = __esm({
36477
36986
  );
36478
36987
  }
36479
36988
  }
36480
- const definition = await fetchFromUrl(metadata.definitionUrl);
36989
+ const definition = await fetchFromUrl(
36990
+ metadata.definitionUrl,
36991
+ this.context.downloadRelayer
36992
+ );
36481
36993
  if (!definition || typeof definition !== "object") {
36482
36994
  throw new Error(
36483
36995
  `Invalid schema definition format for schema ${schemaId}`
36484
36996
  );
36485
36997
  }
36486
- validateDataSchema(definition);
36998
+ validateDataSchemaAgainstMetaSchema(definition);
36487
36999
  const dataSchema = definition;
36488
37000
  if (dataSchema.name !== metadata.name) {
36489
37001
  throw new Error(
@@ -36816,9 +37328,12 @@ var init_schemas = __esm({
36816
37328
  schemas.map(async (schema) => {
36817
37329
  if (!schema.definitionUrl) return;
36818
37330
  try {
36819
- const definition = await fetchFromUrl(schema.definitionUrl);
37331
+ const definition = await fetchFromUrl(
37332
+ schema.definitionUrl,
37333
+ this.context.downloadRelayer
37334
+ );
36820
37335
  if (definition && typeof definition === "object") {
36821
- validateDataSchema(definition);
37336
+ validateDataSchemaAgainstMetaSchema(definition);
36822
37337
  const dataSchema = definition;
36823
37338
  schema.version = dataSchema.version;
36824
37339
  schema.description = dataSchema.description;
@@ -37406,6 +37921,7 @@ init_transactionHandle();
37406
37921
  init_errors();
37407
37922
  init_addresses();
37408
37923
  init_abi();
37924
+ import { getAddress as getAddress3 } from "viem";
37409
37925
 
37410
37926
  // src/utils/grantFiles.ts
37411
37927
  init_errors();
@@ -37454,63 +37970,26 @@ async function storeGrantFile(grantFile, relayerUrl) {
37454
37970
  );
37455
37971
  }
37456
37972
  }
37457
- async function retrieveGrantFile(grantUrl, _relayerUrl) {
37973
+ async function retrieveGrantFile(grantUrl, _relayerUrl, downloadRelayer) {
37458
37974
  try {
37459
37975
  if (grantUrl.startsWith("http") && grantUrl.includes("/ipfs/")) {
37460
37976
  console.warn(
37461
37977
  `\u26A0\uFE0F Grant URL uses HTTP gateway format instead of ipfs:// protocol. Found: ${grantUrl}. Consider using ipfs:// format for better protocol-agnostic storage.`
37462
37978
  );
37463
37979
  }
37464
- if (grantUrl.startsWith("http")) {
37465
- try {
37466
- const timeoutPromise = new Promise((_, reject) => {
37467
- setTimeout(() => reject(new Error("Request timeout")), 1e4);
37468
- });
37469
- const response = await Promise.race([fetch(grantUrl), timeoutPromise]);
37470
- if (response.ok) {
37471
- const text = await response.text();
37472
- const grantFile = JSON.parse(text);
37473
- if (validateGrantFile(grantFile)) {
37474
- return grantFile;
37475
- }
37476
- }
37477
- } catch (directFetchError) {
37478
- console.warn(`Direct fetch failed for ${grantUrl}:`, directFetchError);
37479
- }
37980
+ const { fetchWithRelayer: fetchWithRelayer2 } = await Promise.resolve().then(() => (init_download(), download_exports));
37981
+ const response = await fetchWithRelayer2(grantUrl, downloadRelayer);
37982
+ if (!response.ok) {
37983
+ throw new NetworkError(
37984
+ `Failed to retrieve grant file: HTTP ${response.status}`
37985
+ );
37480
37986
  }
37481
- const { extractIpfsHash: extractIpfsHash2 } = await Promise.resolve().then(() => (init_ipfs(), ipfs_exports));
37482
- const ipfsHash = extractIpfsHash2(grantUrl);
37483
- if (ipfsHash) {
37484
- const gateways = [
37485
- `https://gateway.pinata.cloud/ipfs/${ipfsHash}`,
37486
- `https://ipfs.io/ipfs/${ipfsHash}`,
37487
- `https://dweb.link/ipfs/${ipfsHash}`
37488
- ];
37489
- for (const gatewayUrl of gateways) {
37490
- try {
37491
- const timeoutPromise = new Promise((_, reject) => {
37492
- setTimeout(() => reject(new Error("Request timeout")), 1e4);
37493
- });
37494
- const response = await Promise.race([
37495
- fetch(gatewayUrl),
37496
- timeoutPromise
37497
- ]);
37498
- if (response.ok) {
37499
- const text = await response.text();
37500
- const grantFile = JSON.parse(text);
37501
- if (validateGrantFile(grantFile)) {
37502
- return grantFile;
37503
- }
37504
- }
37505
- } catch (gatewayError) {
37506
- console.warn(`Gateway ${gatewayUrl} failed:`, gatewayError);
37507
- continue;
37508
- }
37509
- }
37987
+ const text = await response.text();
37988
+ const grantFile = JSON.parse(text);
37989
+ if (!validateGrantFile(grantFile)) {
37990
+ throw new NetworkError(`Invalid grant file format from ${grantUrl}`);
37510
37991
  }
37511
- throw new NetworkError(
37512
- `Failed to retrieve grant file from ${grantUrl}. Tried direct fetch${ipfsHash ? " and IPFS gateways" : ""}.`
37513
- );
37992
+ return grantFile;
37514
37993
  } catch (error) {
37515
37994
  if (error instanceof NetworkError) {
37516
37995
  throw error;
@@ -37576,6 +38055,7 @@ function validateGrantFile(data) {
37576
38055
  }
37577
38056
 
37578
38057
  // src/utils/grantValidation.ts
38058
+ import { getAddress } from "viem";
37579
38059
  import Ajv2 from "ajv";
37580
38060
  import addFormats2 from "ajv-formats";
37581
38061
 
@@ -37779,7 +38259,9 @@ function extractFieldFromBusinessError(error) {
37779
38259
  return void 0;
37780
38260
  }
37781
38261
  function validateGranteeAccess(grantFile, requestingAddress) {
37782
- if (grantFile.grantee.toLowerCase() !== requestingAddress.toLowerCase()) {
38262
+ const normalizedGrantee = getAddress(grantFile.grantee);
38263
+ const normalizedRequesting = getAddress(requestingAddress);
38264
+ if (normalizedGrantee !== normalizedRequesting) {
37783
38265
  throw new GranteeMismatchError(
37784
38266
  "Permission denied: requesting address does not match grantee",
37785
38267
  grantFile.grantee,
@@ -37811,6 +38293,7 @@ function validateOperationAccess(grantFile, requestedOperation) {
37811
38293
 
37812
38294
  // src/utils/signatureCache.ts
37813
38295
  init_crypto_utils();
38296
+ import { getAddress as getAddress2 } from "viem";
37814
38297
  var SignatureCache = class {
37815
38298
  static PREFIX = "vana_sig_";
37816
38299
  static DEFAULT_TTL_HOURS = 2;
@@ -37903,7 +38386,7 @@ var SignatureCache = class {
37903
38386
  }
37904
38387
  }
37905
38388
  static getCacheKey(walletAddress, messageHash) {
37906
- return `${this.PREFIX}${walletAddress.toLowerCase()}:${messageHash}`;
38389
+ return `${this.PREFIX}${getAddress2(walletAddress)}:${messageHash}`;
37907
38390
  }
37908
38391
  /**
37909
38392
  * Generate a deterministic hash of a message object for cache key generation
@@ -39176,20 +39659,22 @@ var PermissionsController = class {
39176
39659
  if (!userData || !userData.permissions?.length) {
39177
39660
  return [];
39178
39661
  }
39179
- const onChainGrants = userData.permissions.slice(0, limit).map((permission) => ({
39180
- id: BigInt(permission.id),
39181
- grantUrl: permission.grant,
39182
- grantSignature: permission.signature,
39183
- grantHash: "",
39184
- // Not available in new schema, compute if needed
39185
- nonce: BigInt(permission.nonce),
39186
- addedAtBlock: BigInt(permission.addedAtBlock),
39187
- addedAtTimestamp: BigInt(permission.addedAtTimestamp || "0"),
39188
- transactionHash: permission.transactionHash || "",
39189
- grantor: userAddress,
39190
- active: !permission.endBlock || BigInt(permission.endBlock) === 0n
39191
- // Active if no end block or end block is 0
39192
- }));
39662
+ const onChainGrants = userData.permissions.slice(0, limit).map(
39663
+ (permission) => ({
39664
+ id: BigInt(permission.id),
39665
+ grantUrl: permission.grant,
39666
+ grantSignature: permission.signature,
39667
+ nonce: BigInt(permission.nonce),
39668
+ startBlock: BigInt(permission.startBlock),
39669
+ addedAtBlock: BigInt(permission.addedAtBlock),
39670
+ addedAtTimestamp: BigInt(permission.addedAtTimestamp || "0"),
39671
+ transactionHash: permission.transactionHash || "",
39672
+ grantor: userAddress,
39673
+ grantee: permission.grantee,
39674
+ active: !permission.endBlock || BigInt(permission.endBlock) === 0n
39675
+ // Active if no end block or end block is 0
39676
+ })
39677
+ );
39193
39678
  return onChainGrants.sort((a, b) => {
39194
39679
  if (a.id < b.id) return 1;
39195
39680
  if (a.id > b.id) return -1;
@@ -39267,14 +39752,16 @@ var PermissionsController = class {
39267
39752
  );
39268
39753
  const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
39269
39754
  const userAddress = this.context.walletClient.account?.address || await this.getUserAddress();
39755
+ const normalizedUserAddress = getAddress3(userAddress);
39756
+ const normalizedServerAddress = getAddress3(params.serverAddress);
39270
39757
  const txHash = await this.context.walletClient.writeContract({
39271
39758
  address: DataPortabilityServersAddress,
39272
39759
  abi: DataPortabilityServersAbi,
39273
39760
  functionName: "addAndTrustServerByManager",
39274
39761
  args: [
39275
- userAddress,
39762
+ normalizedUserAddress,
39276
39763
  {
39277
- serverAddress: params.serverAddress,
39764
+ serverAddress: normalizedServerAddress,
39278
39765
  serverUrl: params.serverUrl,
39279
39766
  publicKey: params.publicKey
39280
39767
  }
@@ -39344,9 +39831,10 @@ var PermissionsController = class {
39344
39831
  async submitAddAndTrustServerWithSignature(params) {
39345
39832
  try {
39346
39833
  const nonce = await this.getServersUserNonce();
39834
+ const serverAddress = getAddress3(params.serverAddress);
39347
39835
  const addAndTrustServerInput = {
39348
39836
  nonce,
39349
- serverAddress: params.serverAddress,
39837
+ serverAddress,
39350
39838
  publicKey: params.publicKey,
39351
39839
  serverUrl: params.serverUrl
39352
39840
  };
@@ -40151,11 +40639,13 @@ var PermissionsController = class {
40151
40639
  "DataPortabilityGrantees"
40152
40640
  );
40153
40641
  const DataPortabilityGranteesAbi = getAbi("DataPortabilityGrantees");
40642
+ const ownerAddress = getAddress3(params.owner);
40643
+ const granteeAddress = getAddress3(params.granteeAddress);
40154
40644
  const txHash = await this.context.walletClient.writeContract({
40155
40645
  address: DataPortabilityGranteesAddress,
40156
40646
  abi: DataPortabilityGranteesAbi,
40157
40647
  functionName: "registerGrantee",
40158
- args: [params.owner, params.granteeAddress, params.publicKey],
40648
+ args: [ownerAddress, granteeAddress, params.publicKey],
40159
40649
  account: this.context.walletClient.account || await this.getUserAddress(),
40160
40650
  chain: this.context.walletClient.chain || null
40161
40651
  });
@@ -40182,10 +40672,12 @@ var PermissionsController = class {
40182
40672
  */
40183
40673
  async submitRegisterGranteeWithSignature(params) {
40184
40674
  const nonce = await this.getServersUserNonce();
40675
+ const owner = getAddress3(params.owner);
40676
+ const granteeAddress = getAddress3(params.granteeAddress);
40185
40677
  const registerGranteeInput = {
40186
40678
  nonce,
40187
- owner: params.owner,
40188
- granteeAddress: params.granteeAddress,
40679
+ owner,
40680
+ granteeAddress,
40189
40681
  publicKey: params.publicKey
40190
40682
  };
40191
40683
  const typedData = await this.buildRegisterGranteeTypedData(registerGranteeInput);
@@ -41696,7 +42188,9 @@ var PermissionsController = class {
41696
42188
  init_transactionHandle();
41697
42189
  init_addresses();
41698
42190
  init_abi();
42191
+ init_subgraph();
41699
42192
  import { getContract as getContract2 } from "viem";
42193
+ import { print as print2 } from "graphql";
41700
42194
 
41701
42195
  // src/utils/encryption.ts
41702
42196
  var DEFAULT_ENCRYPTION_SEED = "Please sign to retrieve your encryption key";
@@ -42120,34 +42614,16 @@ var DataController = class {
42120
42614
  );
42121
42615
  }
42122
42616
  try {
42123
- const query = `
42124
- query GetUserFiles($userId: ID!) {
42125
- user(id: $userId) {
42126
- id
42127
- files {
42128
- id
42129
- url
42130
- schemaId
42131
- addedAtBlock
42132
- addedAtTimestamp
42133
- transactionHash
42134
- owner {
42135
- id
42136
- }
42137
- }
42138
- }
42139
- }
42140
- `;
42141
42617
  const response = await fetch(endpoint, {
42142
42618
  method: "POST",
42143
42619
  headers: {
42144
42620
  "Content-Type": "application/json"
42145
42621
  },
42146
42622
  body: JSON.stringify({
42147
- query,
42623
+ query: print2(GetUserFilesDocument),
42148
42624
  variables: {
42149
42625
  userId: owner.toLowerCase()
42150
- // Subgraph stores addresses in lowercase
42626
+ // Subgraph requires lowercase addresses
42151
42627
  }
42152
42628
  })
42153
42629
  });
@@ -42194,7 +42670,10 @@ var DataController = class {
42194
42670
  try {
42195
42671
  proofMap = await this._fetchProofsFromSubgraph(fileIds, endpoint);
42196
42672
  } catch (subgraphError) {
42197
- console.debug("Failed to fetch proofs from subgraph, trying chain:", subgraphError);
42673
+ console.debug(
42674
+ "Failed to fetch proofs from subgraph, trying chain:",
42675
+ subgraphError
42676
+ );
42198
42677
  proofMap = await this._fetchProofsFromChain(fileIds);
42199
42678
  }
42200
42679
  for (const file of userFiles) {
@@ -42217,30 +42696,20 @@ var DataController = class {
42217
42696
  }
42218
42697
  /**
42219
42698
  * Fetches proof data for multiple files from the subgraph.
42220
- *
42699
+ *
42221
42700
  * @private
42222
42701
  * @param fileIds - Array of file IDs to fetch proofs for
42223
42702
  * @param subgraphUrl - The subgraph endpoint URL
42224
42703
  * @returns Map of file IDs to their associated DLP IDs
42225
42704
  */
42226
42705
  async _fetchProofsFromSubgraph(fileIds, subgraphUrl) {
42227
- const query = `
42228
- query GetFileProofs($fileIds: [BigInt!]!) {
42229
- dataRegistryProofs(where: { fileId_in: $fileIds }) {
42230
- fileId
42231
- dlp {
42232
- id
42233
- }
42234
- }
42235
- }
42236
- `;
42237
42706
  const response = await fetch(subgraphUrl, {
42238
42707
  method: "POST",
42239
42708
  headers: {
42240
42709
  "Content-Type": "application/json"
42241
42710
  },
42242
42711
  body: JSON.stringify({
42243
- query,
42712
+ query: print2(GetFileProofsDocument),
42244
42713
  variables: {
42245
42714
  fileIds: fileIds.map((id) => id.toString())
42246
42715
  }
@@ -42278,7 +42747,7 @@ var DataController = class {
42278
42747
  /**
42279
42748
  * Fetches proof data for multiple files from the blockchain.
42280
42749
  * Falls back to this when subgraph is unavailable.
42281
- *
42750
+ *
42282
42751
  * @private
42283
42752
  * @param fileIds - Array of file IDs to fetch proofs for
42284
42753
  * @returns Map of file IDs to their associated DLP IDs
@@ -42344,25 +42813,13 @@ var DataController = class {
42344
42813
  const subgraphUrl = options.subgraphUrl || this.context.subgraphUrl;
42345
42814
  if (subgraphUrl) {
42346
42815
  try {
42347
- const query = `
42348
- query GetDLP($id: ID!) {
42349
- dlp(id: $id) {
42350
- id
42351
- name
42352
- metadata
42353
- status
42354
- address
42355
- owner
42356
- }
42357
- }
42358
- `;
42359
42816
  const response = await fetch(subgraphUrl, {
42360
42817
  method: "POST",
42361
42818
  headers: {
42362
42819
  "Content-Type": "application/json"
42363
42820
  },
42364
42821
  body: JSON.stringify({
42365
- query,
42822
+ query: print2(GetDlpDocument),
42366
42823
  variables: {
42367
42824
  id: dlpId.toString()
42368
42825
  }
@@ -42385,7 +42842,7 @@ var DataController = class {
42385
42842
  return {
42386
42843
  id: parseInt(result.data.dlp.id),
42387
42844
  name: result.data.dlp.name || "",
42388
- metadata: result.data.dlp.metadata,
42845
+ metadata: result.data.dlp.metadata || void 0,
42389
42846
  status: result.data.dlp.status ? parseInt(result.data.dlp.status) : void 0,
42390
42847
  address: result.data.dlp.address,
42391
42848
  owner: result.data.dlp.owner
@@ -42442,7 +42899,7 @@ var DataController = class {
42442
42899
  * // Get first 10 DLPs
42443
42900
  * const dlps = await vana.data.listDLPs({ limit: 10 });
42444
42901
  * dlps.forEach(dlp => console.log(`${dlp.id}: ${dlp.name}`));
42445
- *
42902
+ *
42446
42903
  * // Get next page
42447
42904
  * const nextPage = await vana.data.listDLPs({ limit: 10, offset: 10 });
42448
42905
  * ```
@@ -42599,32 +43056,13 @@ var DataController = class {
42599
43056
  async _getUserPermissionsViaSubgraph(params) {
42600
43057
  const { user, subgraphUrl } = params;
42601
43058
  try {
42602
- const query = `
42603
- query GetUserPermissions($userId: ID!) {
42604
- user(id: $userId) {
42605
- id
42606
- permissions {
42607
- id
42608
- grant
42609
- nonce
42610
- signature
42611
- addedAtBlock
42612
- addedAtTimestamp
42613
- transactionHash
42614
- user {
42615
- id
42616
- }
42617
- }
42618
- }
42619
- }
42620
- `;
42621
43059
  const response = await fetch(subgraphUrl, {
42622
43060
  method: "POST",
42623
43061
  headers: {
42624
43062
  "Content-Type": "application/json"
42625
43063
  },
42626
43064
  body: JSON.stringify({
42627
- query,
43065
+ query: print2(GetUserPermissionsDocument),
42628
43066
  variables: {
42629
43067
  userId: user.toLowerCase()
42630
43068
  }
@@ -42653,7 +43091,7 @@ var DataController = class {
42653
43091
  addedAtBlock: BigInt(permission.addedAtBlock),
42654
43092
  addedAtTimestamp: BigInt(permission.addedAtTimestamp),
42655
43093
  transactionHash: permission.transactionHash,
42656
- user: permission.user.id
43094
+ user
42657
43095
  })).sort((a, b) => Number(b.addedAtTimestamp - a.addedAtTimestamp));
42658
43096
  } catch (error) {
42659
43097
  console.error("Failed to query user permissions from subgraph:", error);
@@ -42825,36 +43263,16 @@ var DataController = class {
42825
43263
  );
42826
43264
  }
42827
43265
  try {
42828
- const query = `
42829
- query GetUserTrustedServers($userId: ID!) {
42830
- user(id: $userId) {
42831
- id
42832
- serverTrusts {
42833
- id
42834
- server {
42835
- id
42836
- serverAddress
42837
- url
42838
- publicKey
42839
- }
42840
- trustedAt
42841
- trustedAtBlock
42842
- untrustedAtBlock
42843
- transactionHash
42844
- }
42845
- }
42846
- }
42847
- `;
42848
43266
  const response = await fetch(graphqlEndpoint, {
42849
43267
  method: "POST",
42850
43268
  headers: {
42851
43269
  "Content-Type": "application/json"
42852
43270
  },
42853
43271
  body: JSON.stringify({
42854
- query,
43272
+ query: print2(GetUserTrustedServersDocument),
42855
43273
  variables: {
42856
43274
  userId: user.toLowerCase()
42857
- // Subgraph stores addresses in lowercase
43275
+ // Subgraph requires lowercase addresses
42858
43276
  }
42859
43277
  })
42860
43278
  });
@@ -43688,19 +44106,31 @@ var DataController = class {
43688
44106
  return await this.submitFilePermission(fileId, account, publicKey);
43689
44107
  }
43690
44108
  /**
43691
- * Submits a file permission transaction and returns the transaction hash immediately.
44109
+ * Submits a file permission transaction to the blockchain.
43692
44110
  *
43693
- * This is the lower-level method that provides maximum control over transaction timing.
44111
+ * @remarks
44112
+ * This method supports gasless transactions via relayer callbacks when configured.
44113
+ * It encrypts the user's encryption key with the recipient's public key before submission.
43694
44114
  * Use this when you want to handle transaction confirmation and event parsing separately.
43695
44115
  *
43696
- * @param fileId - The ID of the file to add permissions for
43697
- * @param account - The address of the account to grant permission to
43698
- * @param publicKey - The public key to encrypt the user's encryption key with
43699
- * @returns Promise resolving to the transaction hash
44116
+ * @param fileId - The ID of the file to grant permission for
44117
+ * @param account - The recipient's wallet address that will access the file
44118
+ * @param publicKey - The recipient's public key for encryption.
44119
+ * Obtain via `vana.server.getIdentity(account).public_key`
44120
+ * @returns Promise resolving to TransactionHandle for tracking the transaction
44121
+ * @throws {Error} When chain ID is not available
44122
+ * @throws {Error} When encryption key generation fails
44123
+ * @throws {Error} When public key encryption fails
44124
+ *
43700
44125
  * @example
43701
44126
  * ```typescript
43702
- * const txHash = await vana.data.submitFilePermission(fileId, account, publicKey);
43703
- * console.log(`Transaction submitted: ${txHash}`);
44127
+ * const tx = await vana.data.submitFilePermission(
44128
+ * fileId,
44129
+ * "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36",
44130
+ * recipientPublicKey
44131
+ * );
44132
+ * const result = await tx.waitForEvents();
44133
+ * console.log(`Permission granted with ID: ${result.permissionId}`);
43704
44134
  * ```
43705
44135
  */
43706
44136
  async submitFilePermission(fileId, account, publicKey) {
@@ -43852,7 +44282,11 @@ var DataController = class {
43852
44282
  */
43853
44283
  async fetch(url) {
43854
44284
  try {
43855
- const response = await fetch(url);
44285
+ const { fetchWithRelayer: fetchWithRelayer2 } = await Promise.resolve().then(() => (init_download(), download_exports));
44286
+ const response = await fetchWithRelayer2(
44287
+ url,
44288
+ this.context.downloadRelayer
44289
+ );
43856
44290
  if (!response.ok) {
43857
44291
  throw new Error(
43858
44292
  `HTTP error! status: ${response.status} ${response.statusText}`
@@ -43918,12 +44352,9 @@ var DataController = class {
43918
44352
  "https://ipfs.io/ipfs/"
43919
44353
  ];
43920
44354
  const gateways = options?.gateways || this.context.ipfsGateways || defaultGateways;
43921
- let cid;
43922
- if (url.startsWith("ipfs://")) {
43923
- cid = url.replace("ipfs://", "");
43924
- } else if (url.startsWith("Qm") || url.startsWith("bafy")) {
43925
- cid = url;
43926
- } else {
44355
+ const { extractIpfsHash: extractIpfsHash2 } = await Promise.resolve().then(() => (init_ipfs(), ipfs_exports));
44356
+ const cid = extractIpfsHash2(url);
44357
+ if (!cid) {
43927
44358
  throw new Error(
43928
44359
  `Invalid IPFS URL format. Expected ipfs://... or a raw CID, got: ${url}`
43929
44360
  );
@@ -43977,6 +44408,17 @@ var DataController = class {
43977
44408
  });
43978
44409
  }
43979
44410
  }
44411
+ if (this.context.downloadRelayer && gateways.length > 0) {
44412
+ try {
44413
+ const relayerUrl = gateways[0].endsWith("/") ? `${gateways[0]}${cid}` : `${gateways[0]}/${cid}`;
44414
+ return await this.context.downloadRelayer.proxyDownload(relayerUrl);
44415
+ } catch (relayerError) {
44416
+ errors.push({
44417
+ gateway: "download-relayer",
44418
+ error: `Proxy failed: ${relayerError instanceof Error ? relayerError.message : "Unknown error"}`
44419
+ });
44420
+ }
44421
+ }
43980
44422
  const errorDetails = errors.map((e) => `${e.gateway}: ${e.error}`).join("\n ");
43981
44423
  throw new Error(
43982
44424
  `Failed to fetch IPFS content ${cid} from all gateways:
@@ -43984,10 +44426,10 @@ var DataController = class {
43984
44426
  );
43985
44427
  }
43986
44428
  /**
43987
- * Validates a data schema against the Vana meta-schema.
44429
+ * Validates a data schema definition against the Vana meta-schema.
43988
44430
  *
43989
- * @param schema - The data schema to validate
43990
- * @returns Assertion that schema is valid (throws if invalid)
44431
+ * @param schema - The data schema definition to validate
44432
+ * @returns The validated DataSchema
43991
44433
  * @throws SchemaValidationError if invalid
43992
44434
  * @example
43993
44435
  * ```typescript
@@ -44004,11 +44446,11 @@ var DataController = class {
44004
44446
  * }
44005
44447
  * };
44006
44448
  *
44007
- * vana.data.validateDataSchema(schema);
44449
+ * const validatedSchema = vana.data.validateDataSchemaAgainstMetaSchema(schema);
44008
44450
  * ```
44009
44451
  */
44010
- validateDataSchema(schema) {
44011
- return validateDataSchema(schema);
44452
+ validateDataSchemaAgainstMetaSchema(schema) {
44453
+ return validateDataSchemaAgainstMetaSchema(schema);
44012
44454
  }
44013
44455
  /**
44014
44456
  * Validates data against a JSON Schema from a data schema.
@@ -44041,9 +44483,9 @@ var DataController = class {
44041
44483
  return validateDataAgainstSchema(data, schema);
44042
44484
  }
44043
44485
  /**
44044
- * Fetches and validates a schema from a URL, then returns the parsed data schema.
44486
+ * Fetches and validates a data schema from a URL, then returns the parsed data schema.
44045
44487
  *
44046
- * @param url - The URL to fetch the schema from
44488
+ * @param url - The URL to fetch the data schema from
44047
44489
  * @returns The validated data schema
44048
44490
  * @throws SchemaValidationError if invalid or fetch fails
44049
44491
  * @example
@@ -44068,6 +44510,73 @@ init_schemas();
44068
44510
 
44069
44511
  // src/controllers/server.ts
44070
44512
  init_errors();
44513
+
44514
+ // src/utils/operationHandle.ts
44515
+ init_errors();
44516
+ var OperationHandle = class {
44517
+ constructor(controller, id) {
44518
+ this.controller = controller;
44519
+ this.id = id;
44520
+ }
44521
+ _resultPromise;
44522
+ /**
44523
+ * Waits for the operation to complete and returns the result.
44524
+ *
44525
+ * @remarks
44526
+ * Results are memoized - multiple calls return the same promise.
44527
+ * The method polls the server at regular intervals until the operation
44528
+ * succeeds, fails, or times out. Returns the raw string result from the
44529
+ * server - callers are responsible for parsing if needed.
44530
+ *
44531
+ * @param options - Optional polling configuration
44532
+ * @returns The operation result as a string when completed
44533
+ * @throws {PersonalServerError} When the operation fails or times out
44534
+ * @example
44535
+ * ```typescript
44536
+ * const result = await handle.waitForResult({
44537
+ * timeout: 60000,
44538
+ * pollingInterval: 500
44539
+ * });
44540
+ * // If expecting JSON, parse it:
44541
+ * const data = JSON.parse(result);
44542
+ * ```
44543
+ */
44544
+ async waitForResult(options) {
44545
+ if (!this._resultPromise) {
44546
+ this._resultPromise = this.pollForCompletion(options);
44547
+ }
44548
+ return this._resultPromise;
44549
+ }
44550
+ async pollForCompletion(options) {
44551
+ const startTime = Date.now();
44552
+ const timeout = options?.timeout ?? 3e4;
44553
+ const interval = options?.pollingInterval ?? 500;
44554
+ while (true) {
44555
+ const result = await this.controller.getOperation(
44556
+ this.id
44557
+ );
44558
+ if (result.status === "succeeded") {
44559
+ if (result.result) {
44560
+ return result.result;
44561
+ }
44562
+ throw new PersonalServerError(
44563
+ "Operation succeeded but returned no result"
44564
+ );
44565
+ }
44566
+ if (result.status === "failed") {
44567
+ throw new PersonalServerError(
44568
+ `Operation ${result.status}: ${result.result || "Unknown error"}`
44569
+ );
44570
+ }
44571
+ if (Date.now() - startTime > timeout) {
44572
+ throw new PersonalServerError(`Operation timed out after ${timeout}ms`);
44573
+ }
44574
+ await new Promise((resolve) => setTimeout(resolve, interval));
44575
+ }
44576
+ }
44577
+ };
44578
+
44579
+ // src/controllers/server.ts
44071
44580
  var ServerController = class {
44072
44581
  constructor(context) {
44073
44582
  this.context = context;
@@ -44149,26 +44658,29 @@ var ServerController = class {
44149
44658
  }
44150
44659
  }
44151
44660
  /**
44152
- * Creates an operation via the personal server API.
44661
+ * Creates a server operation and returns a handle for lifecycle management.
44153
44662
  *
44154
44663
  * @remarks
44155
- * This method submits a computation request to the personal server API.
44156
- * The response includes the operation ID.
44157
- * @param params - The request parameters object
44664
+ * This method submits a computation request to the personal server and returns
44665
+ * an OperationHandle that provides Promise-based methods for waiting on results.
44666
+ * The handle pattern matches TransactionHandle for consistency across async operations.
44667
+ *
44668
+ * @param params - The operation request parameters
44158
44669
  * @param params.permissionId - The permission ID authorizing this operation.
44159
- * Obtain from granted permissions via `vana.permissions.getUserPermissionGrantsOnChain()`.
44160
- * @returns A Promise that resolves to an operation response with status and control URLs
44161
- * @throws {PersonalServerError} When server request fails or parameters are invalid.
44162
- * Verify permissionId exists and is active for the target server.
44163
- * @throws {NetworkError} When personal server API communication fails.
44164
- * Check server URL configuration and network connectivity.
44670
+ * Obtain via `vana.permissions.getUserPermissionGrantsOnChain()`.
44671
+ * @returns An OperationHandle providing access to the operation ID and result methods
44672
+ * @throws {PersonalServerError} When the server request fails or parameters are invalid
44673
+ * @throws {NetworkError} When personal server API communication fails
44165
44674
  * @example
44166
44675
  * ```typescript
44167
- * const response = await vana.server.createOperation({
44168
- * permissionId: 123,
44676
+ * const operation = await vana.server.createOperation({
44677
+ * permissionId: 123
44169
44678
  * });
44170
- *
44171
- * console.log(`Operation created: ${response.id}`);
44679
+ * console.log(`Operation ID: ${operation.id}`);
44680
+ *
44681
+ * // Wait for completion
44682
+ * const result = await operation.waitForResult();
44683
+ * console.log("Result:", result);
44172
44684
  * ```
44173
44685
  */
44174
44686
  async createOperation(params) {
@@ -44184,7 +44696,7 @@ var ServerController = class {
44184
44696
  };
44185
44697
  console.debug("\u{1F50D} Debug - createOperation requestBody", requestBody);
44186
44698
  const response = await this.makeRequest(requestBody);
44187
- return response;
44699
+ return new OperationHandle(this, response.id);
44188
44700
  } catch (error) {
44189
44701
  if (error instanceof Error) {
44190
44702
  if (error instanceof NetworkError || error instanceof SerializationError || error instanceof SignatureError || error instanceof PersonalServerError) {
@@ -44201,30 +44713,20 @@ var ServerController = class {
44201
44713
  }
44202
44714
  }
44203
44715
  /**
44204
- * Polls the status of a computation request for updates and results.
44716
+ * Retrieves the current status and result of a server operation.
44205
44717
  *
44206
44718
  * @remarks
44207
- * This method checks the current status of a computation request by querying
44208
- * the personal server API using the provided operation ID. It returns the current
44209
- * status, any available output, and error information. The method can be
44210
- * called periodically until the operation completes or fails.
44211
- *
44212
- * Common status values include: `starting`, `processing`, `succeeded`, `failed`, `canceled`.
44213
- * @param operationId - The operation ID returned from the initial request submission
44214
- * @returns A Promise that resolves to the current operation response with status and results
44215
- * @throws {NetworkError} When the polling request fails or returns invalid data
44719
+ * Common status values: `starting`, `running`, `succeeded`, `failed`, `canceled`.
44720
+ * When status is `succeeded`, the result field contains the operation output.
44721
+ *
44722
+ * @param operationId - The ID of the operation to query
44723
+ * @returns The operation response containing status, result, and metadata
44724
+ * @throws {NetworkError} When the API request fails or returns invalid data
44216
44725
  * @example
44217
44726
  * ```typescript
44218
- * // Poll until completion
44219
- * let result = await vana.server.getOperation(response.id);
44220
- *
44221
- * while (result.status === "processing") {
44222
- * await new Promise(resolve => setTimeout(resolve, 1000));
44223
- * result = await vana.server.getOperation(response.id);
44224
- * }
44225
- *
44226
- * if (result.status === "succeeded") {
44227
- * console.log("Computation completed:", result.output);
44727
+ * const status = await vana.server.getOperation(operationId);
44728
+ * if (status.status === 'succeeded') {
44729
+ * console.log('Result:', JSON.parse(status.result));
44228
44730
  * }
44229
44731
  * ```
44230
44732
  */
@@ -46236,6 +46738,7 @@ var VanaCore = class {
46236
46738
  /** Handles environment-specific operations like encryption and file systems. */
46237
46739
  platform;
46238
46740
  relayerCallbacks;
46741
+ downloadRelayer;
46239
46742
  storageManager;
46240
46743
  hasRequiredStorage;
46241
46744
  ipfsGateways;
@@ -46265,6 +46768,7 @@ var VanaCore = class {
46265
46768
  this.platform = platform;
46266
46769
  this.validateConfig(config);
46267
46770
  this.relayerCallbacks = config.relayerCallbacks;
46771
+ this.downloadRelayer = config.downloadRelayer;
46268
46772
  this.ipfsGateways = config.ipfsGateways;
46269
46773
  this.defaultPersonalServerUrl = config.defaultPersonalServerUrl;
46270
46774
  this.hasRequiredStorage = hasStorageConfig(config);
@@ -46320,6 +46824,7 @@ var VanaCore = class {
46320
46824
  applicationClient: walletClient,
46321
46825
  // Using same wallet for now
46322
46826
  relayerCallbacks: this.relayerCallbacks,
46827
+ downloadRelayer: this.downloadRelayer,
46323
46828
  storageManager: this.storageManager,
46324
46829
  subgraphUrl,
46325
46830
  platform: this.platform,
@@ -47118,7 +47623,7 @@ var CircuitBreaker = class {
47118
47623
 
47119
47624
  // src/server/handler.ts
47120
47625
  init_errors();
47121
- import { recoverTypedDataAddress } from "viem";
47626
+ import { recoverTypedDataAddress, getAddress as getAddress4 } from "viem";
47122
47627
  async function handleRelayerRequest(sdk, payload) {
47123
47628
  const { typedData, signature, expectedUserAddress } = payload;
47124
47629
  console.debug({
@@ -47141,21 +47646,22 @@ async function handleRelayerRequest(sdk, payload) {
47141
47646
  );
47142
47647
  }
47143
47648
  if (expectedUserAddress) {
47144
- const normalizedSigner = signerAddress.toLowerCase();
47145
- const normalizedExpected = expectedUserAddress.toLowerCase();
47649
+ const normalizedSigner = getAddress4(signerAddress);
47650
+ const normalizedExpected = getAddress4(expectedUserAddress);
47146
47651
  if (normalizedSigner !== normalizedExpected) {
47147
47652
  throw new SignatureError(
47148
47653
  `Security verification failed: Recovered signer address (${normalizedSigner}) does not match expected user address (${normalizedExpected}). This may be due to incorrect EIP-712 domain configuration.`
47149
47654
  );
47150
47655
  }
47151
47656
  }
47152
- switch (typedData.primaryType) {
47657
+ const primaryType = typedData.primaryType;
47658
+ switch (primaryType) {
47153
47659
  case "Permission":
47154
47660
  return sdk.permissions.submitSignedGrant(
47155
47661
  typedData,
47156
47662
  signature
47157
47663
  );
47158
- case "PermissionRevoke":
47664
+ case "RevokePermission":
47159
47665
  return sdk.permissions.submitSignedRevoke(
47160
47666
  typedData,
47161
47667
  signature
@@ -47711,7 +48217,7 @@ export {
47711
48217
  storeGrantFile,
47712
48218
  summarizeGrant,
47713
48219
  validateDataAgainstSchema,
47714
- validateDataSchema,
48220
+ validateDataSchemaAgainstMetaSchema,
47715
48221
  validateGrant,
47716
48222
  validateGrantExpiry,
47717
48223
  validateGrantFile,