@opendatalabs/vana-sdk 0.1.0-alpha.2e77fcc → 0.1.0-alpha.3041a59

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.
Files changed (180) hide show
  1. package/dist/controllers/__tests__/data-consistency-integration.test.d.ts +7 -0
  2. package/dist/controllers/__tests__/operations.processQueue.test.d.ts +1 -0
  3. package/dist/controllers/data.cjs +255 -143
  4. package/dist/controllers/data.cjs.map +1 -1
  5. package/dist/controllers/data.d.ts +25 -10
  6. package/dist/controllers/data.js +268 -146
  7. package/dist/controllers/data.js.map +1 -1
  8. package/dist/controllers/operations.cjs +430 -0
  9. package/dist/controllers/operations.cjs.map +1 -0
  10. package/dist/controllers/operations.d.ts +229 -0
  11. package/dist/controllers/operations.js +406 -0
  12. package/dist/controllers/operations.js.map +1 -0
  13. package/dist/controllers/permissions.cjs +516 -183
  14. package/dist/controllers/permissions.cjs.map +1 -1
  15. package/dist/controllers/permissions.d.ts +126 -28
  16. package/dist/controllers/permissions.js +516 -183
  17. package/dist/controllers/permissions.js.map +1 -1
  18. package/dist/controllers/schemas.cjs +81 -4
  19. package/dist/controllers/schemas.cjs.map +1 -1
  20. package/dist/controllers/schemas.d.ts +41 -0
  21. package/dist/controllers/schemas.js +81 -4
  22. package/dist/controllers/schemas.js.map +1 -1
  23. package/dist/controllers/server.cjs +251 -42
  24. package/dist/controllers/server.cjs.map +1 -1
  25. package/dist/controllers/server.d.ts +111 -14
  26. package/dist/controllers/server.js +251 -42
  27. package/dist/controllers/server.js.map +1 -1
  28. package/dist/core/__tests__/health.test.d.ts +1 -0
  29. package/dist/core/__tests__/inMemoryNonceManager.test.d.ts +1 -0
  30. package/dist/core/__tests__/nonceManager.test.d.ts +1 -0
  31. package/dist/core/__tests__/pollingManager.test.d.ts +4 -0
  32. package/dist/core/health.cjs +289 -0
  33. package/dist/core/health.cjs.map +1 -0
  34. package/dist/core/health.d.ts +143 -0
  35. package/dist/core/health.js +265 -0
  36. package/dist/core/health.js.map +1 -0
  37. package/dist/core/inMemoryNonceManager.cjs +138 -0
  38. package/dist/core/inMemoryNonceManager.cjs.map +1 -0
  39. package/dist/core/inMemoryNonceManager.d.ts +69 -0
  40. package/dist/core/inMemoryNonceManager.js +114 -0
  41. package/dist/core/inMemoryNonceManager.js.map +1 -0
  42. package/dist/core/nonceManager.cjs +304 -0
  43. package/dist/core/nonceManager.cjs.map +1 -0
  44. package/dist/core/nonceManager.d.ts +116 -0
  45. package/dist/core/nonceManager.js +280 -0
  46. package/dist/core/nonceManager.js.map +1 -0
  47. package/dist/core/pollingManager.cjs +292 -0
  48. package/dist/core/pollingManager.cjs.map +1 -0
  49. package/dist/core/pollingManager.d.ts +120 -0
  50. package/dist/core/pollingManager.js +268 -0
  51. package/dist/core/pollingManager.js.map +1 -0
  52. package/dist/core.cjs +5 -0
  53. package/dist/core.cjs.map +1 -1
  54. package/dist/core.d.ts +11 -5
  55. package/dist/core.js +5 -0
  56. package/dist/core.js.map +1 -1
  57. package/dist/crypto/ecies/base.cjs +16 -3
  58. package/dist/crypto/ecies/base.cjs.map +1 -1
  59. package/dist/crypto/ecies/base.js +16 -3
  60. package/dist/crypto/ecies/base.js.map +1 -1
  61. package/dist/errors.cjs +29 -0
  62. package/dist/errors.cjs.map +1 -1
  63. package/dist/errors.d.ts +64 -0
  64. package/dist/errors.js +28 -0
  65. package/dist/errors.js.map +1 -1
  66. package/dist/generated/abi/DataPortabilityGranteesImplementation.cjs +162 -0
  67. package/dist/generated/abi/DataPortabilityGranteesImplementation.cjs.map +1 -1
  68. package/dist/generated/abi/DataPortabilityGranteesImplementation.d.ts +123 -0
  69. package/dist/generated/abi/DataPortabilityGranteesImplementation.js +162 -0
  70. package/dist/generated/abi/DataPortabilityGranteesImplementation.js.map +1 -1
  71. package/dist/generated/abi/index.d.ts +123 -0
  72. package/dist/generated/server/server-exports.cjs +22 -0
  73. package/dist/generated/server/server-exports.cjs.map +1 -1
  74. package/dist/generated/server/server-exports.d.ts +27 -10
  75. package/dist/generated/server/server-exports.js +17 -0
  76. package/dist/generated/server/server-exports.js.map +1 -1
  77. package/dist/generated/server/server.cjs.map +1 -1
  78. package/dist/generated/server/server.d.ts +771 -402
  79. package/dist/generated/subgraph.cjs +797 -32
  80. package/dist/generated/subgraph.cjs.map +1 -1
  81. package/dist/generated/subgraph.d.ts +135 -0
  82. package/dist/generated/subgraph.js +792 -32
  83. package/dist/generated/subgraph.js.map +1 -1
  84. package/dist/index.browser.d.ts +1 -0
  85. package/dist/index.browser.js +2 -0
  86. package/dist/index.browser.js.map +1 -1
  87. package/dist/index.node.cjs +17 -0
  88. package/dist/index.node.cjs.map +1 -1
  89. package/dist/index.node.d.ts +25 -5
  90. package/dist/index.node.js +15 -1
  91. package/dist/index.node.js.map +1 -1
  92. package/dist/lib/__tests__/redisAtomicStore.test.d.ts +1 -0
  93. package/dist/lib/redisAtomicStore.cjs +201 -0
  94. package/dist/lib/redisAtomicStore.cjs.map +1 -0
  95. package/dist/lib/redisAtomicStore.d.ts +120 -0
  96. package/dist/lib/redisAtomicStore.js +177 -0
  97. package/dist/lib/redisAtomicStore.js.map +1 -0
  98. package/dist/server/relayerHandler.cjs +187 -25
  99. package/dist/server/relayerHandler.cjs.map +1 -1
  100. package/dist/server/relayerHandler.d.ts +35 -4
  101. package/dist/server/relayerHandler.js +187 -25
  102. package/dist/server/relayerHandler.js.map +1 -1
  103. package/dist/storage/index.cjs +3 -0
  104. package/dist/storage/index.cjs.map +1 -1
  105. package/dist/storage/index.d.ts +1 -0
  106. package/dist/storage/index.js +2 -0
  107. package/dist/storage/index.js.map +1 -1
  108. package/dist/storage/providers/dropbox.cjs +237 -0
  109. package/dist/storage/providers/dropbox.cjs.map +1 -0
  110. package/dist/storage/providers/dropbox.d.ts +39 -0
  111. package/dist/storage/providers/dropbox.js +215 -0
  112. package/dist/storage/providers/dropbox.js.map +1 -0
  113. package/dist/storage/providers/dropbox.test.d.ts +1 -0
  114. package/dist/tests/data-upload-owner-validation.test.d.ts +1 -0
  115. package/dist/types/atomicStore.cjs +31 -0
  116. package/dist/types/atomicStore.cjs.map +1 -0
  117. package/dist/types/atomicStore.d.ts +236 -0
  118. package/dist/types/atomicStore.js +7 -0
  119. package/dist/types/atomicStore.js.map +1 -0
  120. package/dist/types/config.cjs.map +1 -1
  121. package/dist/types/config.d.ts +3 -3
  122. package/dist/types/config.js.map +1 -1
  123. package/dist/types/controller-context.cjs.map +1 -1
  124. package/dist/types/controller-context.d.ts +4 -3
  125. package/dist/types/data.cjs.map +1 -1
  126. package/dist/types/data.d.ts +7 -4
  127. package/dist/types/index.cjs.map +1 -1
  128. package/dist/types/index.d.ts +4 -2
  129. package/dist/types/index.js.map +1 -1
  130. package/dist/types/operationStore.cjs +17 -0
  131. package/dist/types/operationStore.cjs.map +1 -0
  132. package/dist/types/operationStore.d.ts +171 -0
  133. package/dist/types/operationStore.js +1 -0
  134. package/dist/types/operationStore.js.map +1 -0
  135. package/dist/types/operations.cjs +3 -15
  136. package/dist/types/operations.cjs.map +1 -1
  137. package/dist/types/operations.d.ts +17 -88
  138. package/dist/types/operations.js +2 -13
  139. package/dist/types/operations.js.map +1 -1
  140. package/dist/types/options.cjs +17 -0
  141. package/dist/types/options.cjs.map +1 -0
  142. package/dist/types/options.d.ts +308 -0
  143. package/dist/types/options.js +1 -0
  144. package/dist/types/options.js.map +1 -0
  145. package/dist/types/permissions.cjs.map +1 -1
  146. package/dist/types/permissions.d.ts +4 -0
  147. package/dist/types/personal.cjs.map +1 -1
  148. package/dist/types/personal.d.ts +19 -0
  149. package/dist/types/relayer.cjs.map +1 -1
  150. package/dist/types/relayer.d.ts +10 -10
  151. package/dist/types/utils.cjs.map +1 -1
  152. package/dist/types/utils.d.ts +0 -49
  153. package/dist/utils/__tests__/chainQuery.test.d.ts +1 -0
  154. package/dist/utils/__tests__/subgraphConsistency.test.d.ts +4 -0
  155. package/dist/utils/__tests__/subgraphPagination.test.d.ts +4 -0
  156. package/dist/utils/chainQuery.cjs +107 -0
  157. package/dist/utils/chainQuery.cjs.map +1 -0
  158. package/dist/utils/chainQuery.d.ts +31 -0
  159. package/dist/utils/chainQuery.js +82 -0
  160. package/dist/utils/chainQuery.js.map +1 -0
  161. package/dist/utils/grantFiles.cjs +4 -1
  162. package/dist/utils/grantFiles.cjs.map +1 -1
  163. package/dist/utils/grantFiles.js +4 -1
  164. package/dist/utils/grantFiles.js.map +1 -1
  165. package/dist/utils/subgraphConsistency.cjs +184 -0
  166. package/dist/utils/subgraphConsistency.cjs.map +1 -0
  167. package/dist/utils/subgraphConsistency.d.ts +65 -0
  168. package/dist/utils/subgraphConsistency.js +155 -0
  169. package/dist/utils/subgraphConsistency.js.map +1 -0
  170. package/dist/utils/subgraphMetaCache.cjs +101 -0
  171. package/dist/utils/subgraphMetaCache.cjs.map +1 -0
  172. package/dist/utils/subgraphMetaCache.d.ts +56 -0
  173. package/dist/utils/subgraphMetaCache.js +76 -0
  174. package/dist/utils/subgraphMetaCache.js.map +1 -0
  175. package/dist/utils/subgraphPagination.cjs +104 -0
  176. package/dist/utils/subgraphPagination.cjs.map +1 -0
  177. package/dist/utils/subgraphPagination.d.ts +78 -0
  178. package/dist/utils/subgraphPagination.js +78 -0
  179. package/dist/utils/subgraphPagination.js.map +1 -0
  180. package/package.json +1 -1
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @file Integration tests for data consistency features
3
+ *
4
+ * These tests verify the consistency options work correctly
5
+ * without loading the full DataController implementation
6
+ */
7
+ export {};
@@ -32,11 +32,16 @@ __export(data_exports, {
32
32
  });
33
33
  module.exports = __toCommonJS(data_exports);
34
34
  var import_viem = require("viem");
35
+ var import_pollingManager = require("../core/pollingManager");
35
36
  var import_base = require("./base");
36
37
  var import_addresses = require("../config/addresses");
37
38
  var import_abi = require("../generated/abi");
39
+ var import_errors = require("../errors");
38
40
  var import_subgraph = require("../generated/subgraph");
39
41
  var import_graphql = require("graphql");
42
+ var import_subgraphConsistency = require("../utils/subgraphConsistency");
43
+ var import_subgraphPagination = require("../utils/subgraphPagination");
44
+ var import_chainQuery = require("../utils/chainQuery");
40
45
  var import_encryption = require("../utils/encryption");
41
46
  var import_schemaValidation = require("../utils/schemaValidation");
42
47
  var import_multicall = require("../utils/multicall");
@@ -53,12 +58,18 @@ class DataController extends import_base.BaseController {
53
58
  permissions = [],
54
59
  encrypt = true,
55
60
  providerName,
56
- owner
61
+ owner,
62
+ schemaValidation = "strict"
57
63
  } = params;
64
+ if (encrypt && owner && owner.toLowerCase() !== this.context.userAddress.toLowerCase()) {
65
+ throw new import_errors.InvalidConfigurationError(
66
+ "The 'owner' parameter cannot be different from the connected wallet's address when encryption is enabled. This would create an un-decryptable file."
67
+ );
68
+ }
58
69
  try {
59
70
  let isValid = true;
60
71
  let validationErrors = [];
61
- if (schemaId !== void 0) {
72
+ if (schemaId !== void 0 && schemaValidation !== "skip") {
62
73
  try {
63
74
  const { SchemaController } = await import("./schemas");
64
75
  const schemaController = new SchemaController(this.context);
@@ -82,15 +93,20 @@ class DataController extends import_base.BaseController {
82
93
  }
83
94
  (0, import_schemaValidation.validateDataAgainstSchema)(parsedContent, schema);
84
95
  } catch (error) {
85
- isValid = false;
86
- if (error instanceof Error) {
87
- if (typeof error === "object" && "errors" in error && Array.isArray(error.errors)) {
88
- validationErrors = error.errors;
89
- } else {
90
- validationErrors = [error.message];
96
+ if (schemaValidation === "strict") {
97
+ throw error;
98
+ } else if (schemaValidation === "warn") {
99
+ console.warn(
100
+ '[Vana SDK] Schema validation failed, but continuing due to validation mode "warn"'
101
+ );
102
+ if (error instanceof Error) {
103
+ console.warn(" Validation error:", error.message);
104
+ if (typeof error === "object" && "errors" in error && Array.isArray(error.errors)) {
105
+ console.warn(" Detailed errors:", error.errors);
106
+ }
91
107
  }
92
- } else {
93
- validationErrors = ["Schema validation failed"];
108
+ isValid = false;
109
+ validationErrors = error instanceof Error ? [error.message] : ["Schema validation failed"];
94
110
  }
95
111
  }
96
112
  }
@@ -140,10 +156,17 @@ class DataController extends import_base.BaseController {
140
156
  if (response.type === "error") {
141
157
  throw new Error(response.error);
142
158
  }
143
- if (response.type !== "direct" || !("fileId" in response.result)) {
159
+ if (response.type === "pending") {
160
+ result = await this.pollRelayerForConfirmation(
161
+ response.operationId,
162
+ void 0
163
+ // TODO: Add TransactionOptions to upload method signature
164
+ );
165
+ } else if (response.type === "direct" && typeof response.result === "object" && response.result !== null && "fileId" in response.result) {
166
+ result = response.result;
167
+ } else {
144
168
  throw new Error("Invalid response from relayer");
145
169
  }
146
- result = response.result;
147
170
  } else {
148
171
  const txResult = await this.addFileWithEncryptedPermissionsAndSchema(
149
172
  uploadResult.url,
@@ -435,67 +458,91 @@ class DataController extends import_base.BaseController {
435
458
  * });
436
459
  * ```
437
460
  */
438
- async getUserFiles(params) {
461
+ async getUserFiles(params, options) {
439
462
  const { owner, subgraphUrl } = params;
463
+ let dataSource = options?.source === "chain" ? "chain" : "subgraph";
464
+ if (options?.source === "auto" || !options?.source && options?.minBlock) {
465
+ const endpoint2 = subgraphUrl ?? this.context.subgraphUrl;
466
+ const currentBlock = await this.context.publicClient.getBlockNumber();
467
+ let subgraphBlock;
468
+ if (endpoint2) {
469
+ try {
470
+ const meta = await (0, import_subgraphConsistency.fetchSubgraphMeta)(endpoint2);
471
+ subgraphBlock = meta.blockNumber;
472
+ } catch {
473
+ subgraphBlock = void 0;
474
+ }
475
+ }
476
+ dataSource = (0, import_chainQuery.determineDataSource)(
477
+ options?.source,
478
+ options?.minBlock,
479
+ currentBlock,
480
+ subgraphBlock
481
+ );
482
+ }
483
+ if (dataSource === "chain") {
484
+ const publicClient = this.context.publicClient;
485
+ const chainId = await publicClient.getChainId();
486
+ const contractAddress = (0, import_addresses.getContractAddress)(chainId, "DataRegistry");
487
+ const files = await (0, import_chainQuery.getUserFilesFromChain)(
488
+ publicClient,
489
+ contractAddress,
490
+ owner,
491
+ options?.minBlock ? BigInt(options.minBlock) : void 0
492
+ );
493
+ const limit = options?.fetchAll ? files.length : options?.limit ?? 100;
494
+ const offset = options?.offset ?? 0;
495
+ return files.slice(offset, offset + limit);
496
+ }
440
497
  const endpoint = subgraphUrl ?? this.context.subgraphUrl;
441
498
  if (!endpoint) {
442
499
  throw new Error(
443
500
  "subgraphUrl is required. Please provide a valid subgraph endpoint or configure it in Vana constructor."
444
501
  );
445
502
  }
503
+ if (options?.minBlock || options?.waitForSync) {
504
+ await (0, import_subgraphConsistency.checkSubgraphConsistency)(endpoint, options);
505
+ }
446
506
  try {
447
- const response = await fetch(endpoint, {
448
- method: "POST",
449
- headers: {
450
- "Content-Type": "application/json"
507
+ const orderByMap = {
508
+ id: "id",
509
+ addedAtBlock: "addedAtBlock",
510
+ addedAtTimestamp: "addedAtTimestamp",
511
+ url: "url",
512
+ schemaId: "schemaId"
513
+ };
514
+ const allFiles = await (0, import_subgraphPagination.executePaginatedQuery)({
515
+ endpoint,
516
+ document: import_subgraph.GetUserFilesPaginatedDocument,
517
+ baseVariables: {
518
+ userId: owner.toLowerCase(),
519
+ // Subgraph requires lowercase addresses
520
+ orderBy: (0, import_subgraphPagination.mapOrderByToEnum)(
521
+ options?.orderBy,
522
+ orderByMap,
523
+ "addedAtBlock"
524
+ ),
525
+ orderDirection: (0, import_subgraphPagination.mapOrderDirection)(
526
+ options?.orderDirection,
527
+ "asc",
528
+ "desc"
529
+ )
451
530
  },
452
- body: JSON.stringify({
453
- query: (0, import_graphql.print)(import_subgraph.GetUserFilesDocument),
454
- variables: {
455
- userId: owner.toLowerCase()
456
- // Subgraph requires lowercase addresses
457
- }
458
- })
459
- });
460
- if (!response.ok) {
461
- throw new Error(
462
- `Subgraph request failed: ${response.status} ${response.statusText}`
463
- );
464
- }
465
- const result = await response.json();
466
- if (result.errors) {
467
- throw new Error(
468
- `Subgraph errors: ${result.errors.map((e) => e.message).join(", ")}`
469
- );
470
- }
471
- const user = result.data?.user;
472
- if (!user?.files?.length) {
473
- console.warn("No files found for user:", owner);
474
- return [];
475
- }
476
- const fileMap = /* @__PURE__ */ new Map();
477
- user.files.forEach((file) => {
478
- const fileId = parseInt(file.id);
479
- const userFile = {
480
- id: fileId,
531
+ options,
532
+ extractItems: (data) => data?.user?.files,
533
+ transformItem: (file) => ({
534
+ id: parseInt(file.id),
481
535
  url: file.url,
482
536
  ownerAddress: file.owner.id,
483
537
  addedAtBlock: BigInt(file.addedAtBlock),
484
538
  schemaId: parseInt(file.schemaId),
485
539
  addedAtTimestamp: BigInt(file.addedAtTimestamp),
486
540
  transactionHash: file.transactionHash
487
- };
488
- const existing = fileMap.get(fileId);
489
- if (!existing || userFile.addedAtTimestamp && existing.addedAtTimestamp && userFile.addedAtTimestamp > existing.addedAtTimestamp) {
490
- fileMap.set(fileId, userFile);
491
- }
541
+ })
492
542
  });
493
- const userFiles = Array.from(fileMap.values()).sort(
494
- (a, b) => Number((b.addedAtTimestamp ?? 0n) - (a.addedAtTimestamp ?? 0n))
495
- );
496
- if (userFiles.length > 0) {
543
+ if (allFiles.length > 0) {
497
544
  try {
498
- const fileIds = userFiles.map((f) => f.id);
545
+ const fileIds = allFiles.map((f) => f.id);
499
546
  let proofMap;
500
547
  try {
501
548
  proofMap = await this._fetchProofsFromSubgraph(fileIds, endpoint);
@@ -506,7 +553,7 @@ class DataController extends import_base.BaseController {
506
553
  );
507
554
  proofMap = await this._fetchProofsFromChain(fileIds);
508
555
  }
509
- for (const file of userFiles) {
556
+ for (const file of allFiles) {
510
557
  const dlpIds = proofMap.get(file.id);
511
558
  if (dlpIds && dlpIds.length > 0) {
512
559
  file.dlpIds = dlpIds;
@@ -516,7 +563,7 @@ class DataController extends import_base.BaseController {
516
563
  console.warn("Failed to fetch proof data for files:", error);
517
564
  }
518
565
  }
519
- return userFiles;
566
+ return allFiles;
520
567
  } catch (error) {
521
568
  console.error("Failed to fetch user files from subgraph:", error);
522
569
  throw new Error(
@@ -642,6 +689,9 @@ class DataController extends import_base.BaseController {
642
689
  */
643
690
  async getDLP(dlpId, options = {}) {
644
691
  const subgraphUrl = options.subgraphUrl ?? this.context.subgraphUrl;
692
+ if (subgraphUrl && (options.minBlock || options.waitForSync)) {
693
+ await (0, import_subgraphConsistency.checkSubgraphConsistency)(subgraphUrl, options);
694
+ }
645
695
  if (subgraphUrl) {
646
696
  try {
647
697
  const response = await fetch(subgraphUrl, {
@@ -860,21 +910,33 @@ class DataController extends import_base.BaseController {
860
910
  * @returns Promise resolving to an array of permission objects
861
911
  * @throws Error if both subgraph and RPC queries fail
862
912
  */
863
- async getUserPermissions(params) {
913
+ async getUserPermissions(params, options) {
864
914
  const { user, subgraphUrl } = params;
865
915
  const endpoint = subgraphUrl ?? this.context.subgraphUrl;
916
+ if (endpoint && (options?.minBlock || options?.waitForSync)) {
917
+ await (0, import_subgraphConsistency.checkSubgraphConsistency)(endpoint, options);
918
+ }
866
919
  if (endpoint) {
867
920
  try {
868
- const permissions = await this._getUserPermissionsViaSubgraph({
869
- user,
870
- subgraphUrl: endpoint
871
- });
921
+ const permissions = await this._getUserPermissionsViaSubgraph(
922
+ {
923
+ user,
924
+ subgraphUrl: endpoint
925
+ },
926
+ options
927
+ );
872
928
  return permissions;
873
929
  } catch (error) {
874
930
  console.warn("Subgraph query failed, falling back to RPC:", error);
875
931
  }
876
932
  }
877
- return await this._getUserPermissionsViaRpc({ user });
933
+ const allPermissions = await this._getUserPermissionsViaRpc({ user });
934
+ if (options && !options.fetchAll) {
935
+ const limit = options.limit ?? 100;
936
+ const offset = options.offset ?? 0;
937
+ return allPermissions.slice(offset, offset + limit);
938
+ }
939
+ return allPermissions;
878
940
  }
879
941
  /**
880
942
  * Internal method: Query user permissions via subgraph
@@ -884,46 +946,48 @@ class DataController extends import_base.BaseController {
884
946
  * @param params.subgraphUrl - The subgraph URL endpoint to query
885
947
  * @returns Promise resolving to an array of permission objects
886
948
  */
887
- async _getUserPermissionsViaSubgraph(params) {
949
+ async _getUserPermissionsViaSubgraph(params, options) {
888
950
  const { user, subgraphUrl } = params;
889
951
  try {
890
- const response = await fetch(subgraphUrl, {
891
- method: "POST",
892
- headers: {
893
- "Content-Type": "application/json"
952
+ const orderByMap = {
953
+ id: "id",
954
+ addedAtBlock: "addedAtBlock",
955
+ addedAtTimestamp: "addedAtTimestamp",
956
+ grant: "grant",
957
+ nonce: "nonce",
958
+ startBlock: "startBlock",
959
+ endBlock: "endBlock"
960
+ };
961
+ const permissions = await (0, import_subgraphPagination.executePaginatedQuery)({
962
+ endpoint: subgraphUrl,
963
+ document: import_subgraph.GetUserPermissionsPaginatedDocument,
964
+ baseVariables: {
965
+ userId: user.toLowerCase(),
966
+ orderBy: (0, import_subgraphPagination.mapOrderByToEnum)(
967
+ options?.orderBy,
968
+ orderByMap,
969
+ "addedAtTimestamp"
970
+ ),
971
+ orderDirection: (0, import_subgraphPagination.mapOrderDirection)(
972
+ options?.orderDirection,
973
+ "desc",
974
+ "asc"
975
+ )
894
976
  },
895
- body: JSON.stringify({
896
- query: (0, import_graphql.print)(import_subgraph.GetUserPermissionsDocument),
897
- variables: {
898
- userId: user.toLowerCase()
899
- }
977
+ options,
978
+ extractItems: (data) => data?.user?.permissions,
979
+ transformItem: (permission) => ({
980
+ id: permission.id,
981
+ grant: permission.grant,
982
+ nonce: BigInt(permission.nonce),
983
+ signature: permission.signature,
984
+ addedAtBlock: BigInt(permission.addedAtBlock),
985
+ addedAtTimestamp: BigInt(permission.addedAtTimestamp),
986
+ transactionHash: permission.transactionHash,
987
+ user
900
988
  })
901
989
  });
902
- if (!response.ok) {
903
- throw new Error(
904
- `Subgraph request failed: ${response.status} ${response.statusText}`
905
- );
906
- }
907
- const result = await response.json();
908
- if (result.errors) {
909
- throw new Error(
910
- `Subgraph query errors: ${result.errors.map((e) => e.message).join(", ")}`
911
- );
912
- }
913
- const userData = result.data?.user;
914
- if (!userData?.permissions?.length) {
915
- return [];
916
- }
917
- return userData.permissions.map((permission) => ({
918
- id: permission.id,
919
- grant: permission.grant,
920
- nonce: BigInt(permission.nonce),
921
- signature: permission.signature,
922
- addedAtBlock: BigInt(permission.addedAtBlock),
923
- addedAtTimestamp: BigInt(permission.addedAtTimestamp),
924
- transactionHash: permission.transactionHash,
925
- user
926
- })).sort((a, b) => Number(b.addedAtTimestamp - a.addedAtTimestamp));
990
+ return permissions;
927
991
  } catch (error) {
928
992
  console.error("Failed to query user permissions from subgraph:", error);
929
993
  throw error;
@@ -1056,20 +1120,28 @@ class DataController extends import_base.BaseController {
1056
1120
  * });
1057
1121
  * ```
1058
1122
  */
1059
- async getUserTrustedServers(params) {
1060
- const { user, limit = 50, offset = 0 } = params;
1123
+ async getUserTrustedServers(params, options) {
1124
+ const { user } = params;
1061
1125
  const subgraphUrl = params.subgraphUrl ?? this.context.subgraphUrl;
1126
+ if (subgraphUrl && (options?.minBlock || options?.waitForSync)) {
1127
+ await (0, import_subgraphConsistency.checkSubgraphConsistency)(subgraphUrl, options);
1128
+ }
1062
1129
  if (subgraphUrl) {
1063
1130
  try {
1064
- const servers = await this._getUserTrustedServersViaSubgraph({
1065
- user,
1066
- subgraphUrl
1067
- });
1068
- return limit ? servers.slice(offset, offset + limit) : servers;
1131
+ const servers = await this._getUserTrustedServersViaSubgraph(
1132
+ {
1133
+ user,
1134
+ subgraphUrl
1135
+ },
1136
+ options
1137
+ );
1138
+ return servers;
1069
1139
  } catch (error) {
1070
1140
  console.warn("Subgraph query failed, falling back to RPC:", error);
1071
1141
  }
1072
1142
  }
1143
+ const limit = options?.fetchAll ? Number.MAX_SAFE_INTEGER : options?.limit ?? 100;
1144
+ const offset = options?.offset ?? 0;
1073
1145
  const rpcResult = await this._getUserTrustedServersViaRpc({
1074
1146
  user,
1075
1147
  limit,
@@ -1085,7 +1157,7 @@ class DataController extends import_base.BaseController {
1085
1157
  * @param params.subgraphUrl - The subgraph URL endpoint to query
1086
1158
  * @returns Promise resolving to an array of trusted server objects
1087
1159
  */
1088
- async _getUserTrustedServersViaSubgraph(params) {
1160
+ async _getUserTrustedServersViaSubgraph(params, options) {
1089
1161
  const { user, subgraphUrl } = params;
1090
1162
  const graphqlEndpoint = subgraphUrl;
1091
1163
  if (!graphqlEndpoint) {
@@ -1094,42 +1166,46 @@ class DataController extends import_base.BaseController {
1094
1166
  );
1095
1167
  }
1096
1168
  try {
1097
- const response = await fetch(graphqlEndpoint, {
1098
- method: "POST",
1099
- headers: {
1100
- "Content-Type": "application/json"
1169
+ const orderByMap = {
1170
+ id: "id",
1171
+ trustedAt: "trustedAt",
1172
+ trustedAtBlock: "trustedAtBlock",
1173
+ server: "server",
1174
+ user: "user"
1175
+ };
1176
+ const serverTrusts = await (0, import_subgraphPagination.executePaginatedQuery)({
1177
+ endpoint: graphqlEndpoint,
1178
+ document: import_subgraph.GetUserTrustedServersPaginatedDocument,
1179
+ baseVariables: {
1180
+ userId: user.toLowerCase(),
1181
+ // Subgraph requires lowercase addresses
1182
+ orderBy: (0, import_subgraphPagination.mapOrderByToEnum)(
1183
+ options?.orderBy,
1184
+ orderByMap,
1185
+ "trustedAtBlock"
1186
+ ),
1187
+ orderDirection: (0, import_subgraphPagination.mapOrderDirection)(
1188
+ options?.orderDirection,
1189
+ "desc",
1190
+ "asc"
1191
+ )
1101
1192
  },
1102
- body: JSON.stringify({
1103
- query: (0, import_graphql.print)(import_subgraph.GetUserTrustedServersDocument),
1104
- variables: {
1105
- userId: user.toLowerCase()
1106
- // Subgraph requires lowercase addresses
1107
- }
1193
+ options,
1194
+ extractItems: (data) => {
1195
+ const trusts = data?.user?.serverTrusts ?? [];
1196
+ return trusts.filter((trust) => !trust.untrustedAtBlock);
1197
+ },
1198
+ transformItem: (trust) => ({
1199
+ id: trust.server.id,
1200
+ serverAddress: trust.server.serverAddress,
1201
+ serverUrl: trust.server.url,
1202
+ trustedAt: BigInt(trust.trustedAt),
1203
+ user,
1204
+ name: ""
1205
+ // Not available in new schema, will be empty
1108
1206
  })
1109
1207
  });
1110
- if (!response.ok) {
1111
- throw new Error(
1112
- `Subgraph request failed: ${response.status} ${response.statusText}`
1113
- );
1114
- }
1115
- const result = await response.json();
1116
- if (result.errors) {
1117
- throw new Error(
1118
- `Subgraph query errors: ${result.errors.map((e) => e.message).join(", ")}`
1119
- );
1120
- }
1121
- if (!result.data?.user) {
1122
- return [];
1123
- }
1124
- return (result.data.user.serverTrusts ?? []).filter((trust) => !trust.untrustedAtBlock).map((trust) => ({
1125
- id: trust.server.id,
1126
- serverAddress: trust.server.serverAddress,
1127
- serverUrl: trust.server.url,
1128
- trustedAt: BigInt(trust.trustedAt),
1129
- user,
1130
- name: ""
1131
- // Not available in new schema, will be empty
1132
- }));
1208
+ return serverTrusts;
1133
1209
  } catch (error) {
1134
1210
  console.error("Failed to query trusted servers from subgraph:", error);
1135
1211
  throw error;
@@ -1969,10 +2045,18 @@ class DataController extends import_base.BaseController {
1969
2045
  if (response.type === "error") {
1970
2046
  throw new Error(response.error);
1971
2047
  }
1972
- if (response.type !== "direct" || !("fileId" in response.result)) {
2048
+ let result;
2049
+ if (response.type === "pending") {
2050
+ result = await this.pollRelayerForConfirmation(
2051
+ response.operationId,
2052
+ void 0
2053
+ // TODO: Add TransactionOptions to upload method signature
2054
+ );
2055
+ } else if (response.type === "direct" && typeof response.result === "object" && response.result !== null && "fileId" in response.result) {
2056
+ result = response.result;
2057
+ } else {
1973
2058
  throw new Error("Invalid response from relayer");
1974
2059
  }
1975
- const result = response.result;
1976
2060
  return {
1977
2061
  fileId: result.fileId,
1978
2062
  url: uploadResult.url,
@@ -2061,7 +2145,15 @@ class DataController extends import_base.BaseController {
2061
2145
  );
2062
2146
  }
2063
2147
  }
2064
- const finalFilename = filename ?? `upload-${Date.now()}.dat`;
2148
+ const finalFilename = (() => {
2149
+ if (filename) {
2150
+ if (encrypt && !filename.endsWith(".enc")) {
2151
+ return `${filename}.enc`;
2152
+ }
2153
+ return filename;
2154
+ }
2155
+ return encrypt ? `upload-${Date.now()}.enc` : `upload-${Date.now()}.dat`;
2156
+ })();
2065
2157
  const uploadResult = await this.context.storageManager.upload(
2066
2158
  finalBlob,
2067
2159
  finalFilename,
@@ -2513,6 +2605,26 @@ class DataController extends import_base.BaseController {
2513
2605
  async fetchAndValidateSchema(url) {
2514
2606
  return (0, import_schemaValidation.fetchAndValidateSchema)(url);
2515
2607
  }
2608
+ /**
2609
+ * Polls for confirmation of a relayer operation.
2610
+ * @internal
2611
+ */
2612
+ async pollRelayerForConfirmation(operationId, options) {
2613
+ if (!this.context.relayer) {
2614
+ throw new Error("Relayer not configured for polling");
2615
+ }
2616
+ const pollingManager = new import_pollingManager.PollingManager(this.context.relayer);
2617
+ const result = await pollingManager.startPolling(operationId, {
2618
+ signal: options?.signal,
2619
+ onStatusUpdate: options?.onStatusUpdate,
2620
+ ...options?.pollingOptions
2621
+ });
2622
+ return {
2623
+ fileId: 0,
2624
+ // This would need to be extracted from transaction events
2625
+ transactionHash: result.hash
2626
+ };
2627
+ }
2516
2628
  }
2517
2629
  // Annotate the CommonJS export names for ESM import in node:
2518
2630
  0 && (module.exports = {