@opendatalabs/vana-sdk 0.1.0-alpha.f35bb9c → 0.1.0-alpha.f48b66e

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 (95) hide show
  1. package/dist/controllers/__tests__/data-consistency-integration.test.d.ts +7 -0
  2. package/dist/controllers/base.cjs +33 -0
  3. package/dist/controllers/base.cjs.map +1 -1
  4. package/dist/controllers/base.d.ts +10 -0
  5. package/dist/controllers/base.js +33 -0
  6. package/dist/controllers/base.js.map +1 -1
  7. package/dist/controllers/data.cjs +210 -147
  8. package/dist/controllers/data.cjs.map +1 -1
  9. package/dist/controllers/data.d.ts +15 -12
  10. package/dist/controllers/data.js +223 -150
  11. package/dist/controllers/data.js.map +1 -1
  12. package/dist/controllers/permissions.cjs +203 -94
  13. package/dist/controllers/permissions.cjs.map +1 -1
  14. package/dist/controllers/permissions.d.ts +20 -11
  15. package/dist/controllers/permissions.js +203 -94
  16. package/dist/controllers/permissions.js.map +1 -1
  17. package/dist/controllers/schemas.cjs +11 -1
  18. package/dist/controllers/schemas.cjs.map +1 -1
  19. package/dist/controllers/schemas.d.ts +2 -0
  20. package/dist/controllers/schemas.js +11 -1
  21. package/dist/controllers/schemas.js.map +1 -1
  22. package/dist/core.cjs +4 -1
  23. package/dist/core.cjs.map +1 -1
  24. package/dist/core.d.ts +2 -1
  25. package/dist/core.js +4 -1
  26. package/dist/core.js.map +1 -1
  27. package/dist/generated/subgraph.cjs +797 -32
  28. package/dist/generated/subgraph.cjs.map +1 -1
  29. package/dist/generated/subgraph.d.ts +135 -0
  30. package/dist/generated/subgraph.js +792 -32
  31. package/dist/generated/subgraph.js.map +1 -1
  32. package/dist/index.node.cjs +2 -0
  33. package/dist/index.node.cjs.map +1 -1
  34. package/dist/index.node.d.ts +27 -4
  35. package/dist/index.node.js +2 -0
  36. package/dist/index.node.js.map +1 -1
  37. package/dist/server/relayerHandler.cjs +201 -87
  38. package/dist/server/relayerHandler.cjs.map +1 -1
  39. package/dist/server/relayerHandler.d.ts +3 -1
  40. package/dist/server/relayerHandler.js +201 -87
  41. package/dist/server/relayerHandler.js.map +1 -1
  42. package/dist/types/config.cjs.map +1 -1
  43. package/dist/types/config.d.ts +32 -0
  44. package/dist/types/config.js.map +1 -1
  45. package/dist/types/controller-context.cjs.map +1 -1
  46. package/dist/types/controller-context.d.ts +3 -1
  47. package/dist/types/data.cjs.map +1 -1
  48. package/dist/types/data.d.ts +0 -4
  49. package/dist/types/generics.cjs.map +1 -1
  50. package/dist/types/generics.d.ts +1 -1
  51. package/dist/types/index.cjs.map +1 -1
  52. package/dist/types/index.d.ts +4 -2
  53. package/dist/types/index.js.map +1 -1
  54. package/dist/types/operations.cjs.map +1 -1
  55. package/dist/types/operations.d.ts +33 -0
  56. package/dist/types/operations.js.map +1 -1
  57. package/dist/types/options.cjs +17 -0
  58. package/dist/types/options.cjs.map +1 -0
  59. package/dist/types/options.d.ts +213 -0
  60. package/dist/types/options.js +1 -0
  61. package/dist/types/options.js.map +1 -0
  62. package/dist/types/permissions.cjs.map +1 -1
  63. package/dist/types/permissions.d.ts +2 -0
  64. package/dist/types/relayer.cjs.map +1 -1
  65. package/dist/types/relayer.d.ts +19 -8
  66. package/dist/types/utils.cjs.map +1 -1
  67. package/dist/types/utils.d.ts +0 -49
  68. package/dist/utils/__tests__/subgraphConsistency.test.d.ts +4 -0
  69. package/dist/utils/__tests__/subgraphPagination.test.d.ts +4 -0
  70. package/dist/utils/chainQuery.cjs +107 -0
  71. package/dist/utils/chainQuery.cjs.map +1 -0
  72. package/dist/utils/chainQuery.d.ts +31 -0
  73. package/dist/utils/chainQuery.js +82 -0
  74. package/dist/utils/chainQuery.js.map +1 -0
  75. package/dist/utils/ipfs.cjs +2 -4
  76. package/dist/utils/ipfs.cjs.map +1 -1
  77. package/dist/utils/ipfs.d.ts +1 -1
  78. package/dist/utils/ipfs.js +2 -4
  79. package/dist/utils/ipfs.js.map +1 -1
  80. package/dist/utils/subgraphConsistency.cjs +184 -0
  81. package/dist/utils/subgraphConsistency.cjs.map +1 -0
  82. package/dist/utils/subgraphConsistency.d.ts +65 -0
  83. package/dist/utils/subgraphConsistency.js +155 -0
  84. package/dist/utils/subgraphConsistency.js.map +1 -0
  85. package/dist/utils/subgraphMetaCache.cjs +101 -0
  86. package/dist/utils/subgraphMetaCache.cjs.map +1 -0
  87. package/dist/utils/subgraphMetaCache.d.ts +56 -0
  88. package/dist/utils/subgraphMetaCache.js +76 -0
  89. package/dist/utils/subgraphMetaCache.js.map +1 -0
  90. package/dist/utils/subgraphPagination.cjs +104 -0
  91. package/dist/utils/subgraphPagination.cjs.map +1 -0
  92. package/dist/utils/subgraphPagination.d.ts +78 -0
  93. package/dist/utils/subgraphPagination.js +78 -0
  94. package/dist/utils/subgraphPagination.js.map +1 -0
  95. package/package.json +3 -1
@@ -1,7 +1,7 @@
1
1
  import type { Address, Hash } from "viem";
2
- import type { GrantPermissionParams, RevokePermissionParams, PermissionGrantTypedData, GenericTypedData, OnChainPermissionGrant, GetUserPermissionsOptions, AddAndTrustServerParams, TrustServerParams, UntrustServerParams, AddAndTrustServerTypedData, TrustServerTypedData, TrustedServerInfo, PaginatedTrustedServers, TrustedServerQueryOptions, BatchServerInfoResult, ServerTrustStatus, GrantFile, Grantee, GranteeInfo, RegisterGranteeParams, GranteeQueryOptions, PaginatedGrantees, ServerInfo, ServerFilesAndPermissionParams, ServerFilesAndPermissionTypedData, TransactionOptions } from "../types/index";
2
+ import type { TransactionOptions, TransactionResult } from "../types/operations";
3
+ import type { GrantPermissionParams, RevokePermissionParams, PermissionGrantTypedData, GenericTypedData, OnChainPermissionGrant, GetUserPermissionsOptions, AddAndTrustServerParams, TrustServerParams, UntrustServerParams, AddAndTrustServerTypedData, TrustServerTypedData, TrustedServerInfo, PaginatedTrustedServers, TrustedServerQueryOptions, BatchServerInfoResult, ServerTrustStatus, GrantFile, Grantee, GranteeInfo, RegisterGranteeParams, GranteeQueryOptions, PaginatedGrantees, ServerInfo, ServerFilesAndPermissionParams, ServerFilesAndPermissionTypedData } from "../types/index";
3
4
  import type { PermissionGrantResult, PermissionRevokeResult, ServerTrustResult } from "../types/transactionResults";
4
- import type { TransactionResult } from "../types/operations";
5
5
  import type { PermissionInfo } from "../types/permissions";
6
6
  /**
7
7
  * Provides shared configuration and services for all SDK controllers.
@@ -101,7 +101,7 @@ export declare class PermissionsController extends BaseController {
101
101
  * await vana.permissions.revoke({ permissionId: result.permissionId });
102
102
  * ```
103
103
  */
104
- grant(params: GrantPermissionParams): Promise<PermissionGrantResult>;
104
+ grant(params: GrantPermissionParams, options?: TransactionOptions): Promise<PermissionGrantResult>;
105
105
  /**
106
106
  * Submits a permission grant transaction and returns a handle for flexible result access.
107
107
  *
@@ -127,7 +127,7 @@ export declare class PermissionsController extends BaseController {
127
127
  * console.log(`Permission ID: ${eventData.permissionId}`);
128
128
  * ```
129
129
  */
130
- submitPermissionGrant(params: GrantPermissionParams): Promise<TransactionResult<"DataPortabilityPermissions", "addPermission">>;
130
+ submitPermissionGrant(params: GrantPermissionParams, options?: TransactionOptions): Promise<TransactionResult<"DataPortabilityPermissions", "addPermission">>;
131
131
  /**
132
132
  * Prepares a permission grant with preview before signing.
133
133
  *
@@ -153,7 +153,7 @@ export declare class PermissionsController extends BaseController {
153
153
  * const transactionHash = await confirm();
154
154
  * ```
155
155
  */
156
- prepareGrant(params: GrantPermissionParams): Promise<{
156
+ prepareGrant(params: GrantPermissionParams, options?: TransactionOptions): Promise<{
157
157
  preview: GrantFile;
158
158
  confirm: () => Promise<PermissionGrantResult>;
159
159
  }>;
@@ -225,7 +225,7 @@ export declare class PermissionsController extends BaseController {
225
225
  * );
226
226
  * ```
227
227
  */
228
- submitSignedGrant(typedData: PermissionGrantTypedData, signature: Hash): Promise<TransactionResult<"DataPortabilityPermissions", "addPermission">>;
228
+ submitSignedGrant(typedData: PermissionGrantTypedData, signature: Hash, options?: TransactionOptions): Promise<TransactionResult<"DataPortabilityPermissions", "addPermission">>;
229
229
  /**
230
230
  * Submits an already-signed trust server transaction to the blockchain.
231
231
  *
@@ -247,7 +247,7 @@ export declare class PermissionsController extends BaseController {
247
247
  * const result = await txHandle.waitForEvents();
248
248
  * ```
249
249
  */
250
- submitSignedTrustServer(typedData: TrustServerTypedData, signature: Hash): Promise<TransactionResult<"DataPortabilityServers", "trustServerWithSignature">>;
250
+ submitSignedTrustServer(typedData: TrustServerTypedData, signature: Hash, options?: TransactionOptions): Promise<TransactionResult<"DataPortabilityServers", "trustServerWithSignature">>;
251
251
  /**
252
252
  * Submits an already-signed add and trust server transaction to the blockchain.
253
253
  *
@@ -269,7 +269,7 @@ export declare class PermissionsController extends BaseController {
269
269
  * const result = await txHandle.waitForEvents();
270
270
  * ```
271
271
  */
272
- submitSignedAddAndTrustServer(typedData: AddAndTrustServerTypedData, signature: Hash): Promise<TransactionResult<"DataPortabilityServers", "addAndTrustServerWithSignature">>;
272
+ submitSignedAddAndTrustServer(typedData: AddAndTrustServerTypedData, signature: Hash, _options?: TransactionOptions): Promise<TransactionResult<"DataPortabilityServers", "addAndTrustServerWithSignature">>;
273
273
  /**
274
274
  * Internal method to submit a signed grant and wait for events.
275
275
  *
@@ -288,6 +288,15 @@ export declare class PermissionsController extends BaseController {
288
288
  * @returns Promise resolving to PermissionGrantResult with parsed events
289
289
  */
290
290
  private confirmGrantInternalWithEvents;
291
+ /**
292
+ * Polls the relayer for confirmation of a pending operation.
293
+ *
294
+ * @param operationId - The operation ID to poll
295
+ * @returns Promise resolving to the confirmed hash
296
+ * @throws {Error} When the operation fails or times out
297
+ * @internal
298
+ */
299
+ private pollRelayerForConfirmation;
291
300
  /**
292
301
  * Submits an already-signed permission revoke transaction to the blockchain.
293
302
  *
@@ -309,7 +318,7 @@ export declare class PermissionsController extends BaseController {
309
318
  * const result = await txHandle.waitForEvents();
310
319
  * ```
311
320
  */
312
- submitSignedRevoke(typedData: GenericTypedData, signature: Hash): Promise<TransactionResult<"DataPortabilityPermissions", "revokePermissionWithSignature">>;
321
+ submitSignedRevoke(typedData: GenericTypedData, signature: Hash, _options?: TransactionOptions): Promise<TransactionResult<"DataPortabilityPermissions", "revokePermissionWithSignature">>;
313
322
  /**
314
323
  * Submits an already-signed untrust server transaction to the blockchain.
315
324
  *
@@ -331,7 +340,7 @@ export declare class PermissionsController extends BaseController {
331
340
  * const result = await txHandle.waitForEvents();
332
341
  * ```
333
342
  */
334
- submitSignedUntrustServer(typedData: GenericTypedData, signature: Hash): Promise<TransactionResult<"DataPortabilityServers", "untrustServerWithSignature">>;
343
+ submitSignedUntrustServer(typedData: GenericTypedData, signature: Hash, _options?: TransactionOptions): Promise<TransactionResult<"DataPortabilityServers", "untrustServerWithSignature">>;
335
344
  /**
336
345
  * Submits a signed transaction directly to the blockchain.
337
346
  *
@@ -1183,7 +1192,7 @@ export declare class PermissionsController extends BaseController {
1183
1192
  * @throws {BlockchainError} When permission addition fails
1184
1193
  * @throws {NetworkError} When network communication fails
1185
1194
  */
1186
- submitSignedAddPermission(typedData: GenericTypedData, signature: Hash): Promise<TransactionResult<"DataPortabilityPermissions", "addPermission">>;
1195
+ submitSignedAddPermission(typedData: GenericTypedData, signature: Hash, options?: TransactionOptions): Promise<TransactionResult<"DataPortabilityPermissions", "addPermission">>;
1187
1196
  /**
1188
1197
  * Submits server files and permissions with signature to the blockchain, supporting schema validation and gasless transactions.
1189
1198
  *
@@ -57,10 +57,14 @@ class PermissionsController extends BaseController {
57
57
  * await vana.permissions.revoke({ permissionId: result.permissionId });
58
58
  * ```
59
59
  */
60
- async grant(params) {
60
+ async grant(params, options) {
61
61
  this.assertWallet();
62
62
  const { typedData, signature } = await this.createAndSign(params);
63
- const result = await this.submitSignedGrantWithEvents(typedData, signature);
63
+ const result = await this.submitSignedGrantWithEvents(
64
+ typedData,
65
+ signature,
66
+ options
67
+ );
64
68
  return result;
65
69
  }
66
70
  /**
@@ -88,10 +92,10 @@ class PermissionsController extends BaseController {
88
92
  * console.log(`Permission ID: ${eventData.permissionId}`);
89
93
  * ```
90
94
  */
91
- async submitPermissionGrant(params) {
95
+ async submitPermissionGrant(params, options) {
92
96
  this.assertWallet();
93
97
  const { typedData, signature } = await this.createAndSign(params);
94
- return await this.submitSignedGrant(typedData, signature);
98
+ return await this.submitSignedGrant(typedData, signature, options);
95
99
  }
96
100
  /**
97
101
  * Prepares a permission grant with preview before signing.
@@ -118,7 +122,7 @@ class PermissionsController extends BaseController {
118
122
  * const transactionHash = await confirm();
119
123
  * ```
120
124
  */
121
- async prepareGrant(params) {
125
+ async prepareGrant(params, options) {
122
126
  this.assertWallet();
123
127
  try {
124
128
  const grantFile = createGrantFile(params);
@@ -126,7 +130,11 @@ class PermissionsController extends BaseController {
126
130
  return {
127
131
  preview: grantFile,
128
132
  confirm: async () => {
129
- return await this.confirmGrantInternalWithEvents(params, grantFile);
133
+ return await this.confirmGrantInternalWithEvents(
134
+ params,
135
+ grantFile,
136
+ options
137
+ );
130
138
  }
131
139
  };
132
140
  } catch (error) {
@@ -158,7 +166,7 @@ class PermissionsController extends BaseController {
158
166
  * @throws {NetworkError} When IPFS upload fails
159
167
  * @throws {SignatureError} When user rejects the signature
160
168
  */
161
- async confirmGrantInternal(params, grantFile) {
169
+ async confirmGrantInternal(params, grantFile, options) {
162
170
  try {
163
171
  let { grantUrl } = params;
164
172
  console.debug("\u{1F50D} Debug - Grant URL from params:", grantUrl);
@@ -183,7 +191,7 @@ class PermissionsController extends BaseController {
183
191
  if (response.type === "error") {
184
192
  throw new Error(response.error);
185
193
  }
186
- if (response.type === "direct" && typeof response.result === "object" && "url" in response.result) {
194
+ if (response.type === "direct" && typeof response.result === "object" && response.result !== null && "url" in response.result) {
187
195
  grantUrl = response.result.url;
188
196
  } else {
189
197
  throw new Error("Invalid response from relayer for grant storage");
@@ -219,7 +227,7 @@ class PermissionsController extends BaseController {
219
227
  nonce
220
228
  });
221
229
  const signature = await this.signTypedData(typedData);
222
- return await this.submitSignedGrant(typedData, signature);
230
+ return await this.submitSignedGrant(typedData, signature, options);
223
231
  } catch (error) {
224
232
  if (error instanceof Error) {
225
233
  if (error instanceof RelayerError || error instanceof UserRejectedRequestError || error instanceof SerializationError || error instanceof SignatureError || error instanceof NetworkError || error instanceof NonceError) {
@@ -291,7 +299,7 @@ class PermissionsController extends BaseController {
291
299
  if (response.type === "error") {
292
300
  throw new Error(response.error);
293
301
  }
294
- if (response.type === "direct" && typeof response.result === "object" && "url" in response.result) {
302
+ if (response.type === "direct" && typeof response.result === "object" && response.result !== null && "url" in response.result) {
295
303
  grantUrl = response.result.url;
296
304
  } else {
297
305
  throw new Error("Invalid response from relayer for grant storage");
@@ -364,7 +372,7 @@ class PermissionsController extends BaseController {
364
372
  * );
365
373
  * ```
366
374
  */
367
- async submitSignedGrant(typedData, signature) {
375
+ async submitSignedGrant(typedData, signature, options) {
368
376
  try {
369
377
  console.debug(
370
378
  "\u{1F50D} Debug - submitSignedGrant called with typed data:",
@@ -382,26 +390,40 @@ class PermissionsController extends BaseController {
382
390
  signature,
383
391
  expectedUserAddress: this.context.userAddress
384
392
  });
385
- let hash;
386
- if (response.type === "signed") {
387
- hash = response.hash;
388
- } else if (response.type === "error") {
393
+ if (response.type === "error") {
389
394
  throw new Error(`Relayer error: ${response.error}`);
395
+ }
396
+ let finalHash;
397
+ if (response.type === "submitted") {
398
+ finalHash = response.hash;
399
+ } else if (response.type === "pending") {
400
+ const pollResult = await this.pollRelayerForConfirmation(
401
+ response.operationId
402
+ );
403
+ finalHash = pollResult.hash;
404
+ } else if (response.type === "confirmed") {
405
+ finalHash = response.hash;
406
+ } else if (response.type === "signed") {
407
+ finalHash = response.hash;
390
408
  } else {
391
409
  throw new Error(
392
- "Invalid response from relayer: expected signed transaction"
410
+ "Invalid response from relayer: unexpected response type"
393
411
  );
394
412
  }
395
413
  const account = this.context.walletClient?.account ?? this.context.userAddress;
396
414
  const { tx } = await import("../utils/transactionHelpers");
397
415
  return tx({
398
- hash,
416
+ hash: finalHash,
399
417
  from: typeof account === "string" ? account : account.address,
400
418
  contract: "DataPortabilityPermissions",
401
419
  fn: "addPermission"
402
420
  });
403
421
  } else {
404
- return await this.submitDirectTransaction(typedData, signature);
422
+ return await this.submitDirectTransaction(
423
+ typedData,
424
+ signature,
425
+ options
426
+ );
405
427
  }
406
428
  } catch (error) {
407
429
  if (error instanceof RelayerError || error instanceof NetworkError || error instanceof UserRejectedRequestError || error instanceof SignatureError || error instanceof NonceError) {
@@ -434,7 +456,7 @@ class PermissionsController extends BaseController {
434
456
  * const result = await txHandle.waitForEvents();
435
457
  * ```
436
458
  */
437
- async submitSignedTrustServer(typedData, signature) {
459
+ async submitSignedTrustServer(typedData, signature, options) {
438
460
  try {
439
461
  const trustServerInput = {
440
462
  nonce: BigInt(typedData.message.nonce),
@@ -442,7 +464,8 @@ class PermissionsController extends BaseController {
442
464
  };
443
465
  const hash = await this.submitTrustServerTransaction(
444
466
  trustServerInput,
445
- signature
467
+ signature,
468
+ options
446
469
  );
447
470
  const account = this.context.userAddress;
448
471
  const { tx } = await import("../utils/transactionHelpers");
@@ -497,7 +520,7 @@ class PermissionsController extends BaseController {
497
520
  * const result = await txHandle.waitForEvents();
498
521
  * ```
499
522
  */
500
- async submitSignedAddAndTrustServer(typedData, signature) {
523
+ async submitSignedAddAndTrustServer(typedData, signature, _options) {
501
524
  try {
502
525
  const addAndTrustServerInput = {
503
526
  nonce: BigInt(typedData.message.nonce),
@@ -535,8 +558,12 @@ class PermissionsController extends BaseController {
535
558
  * @param signature - The user's signature authorizing the transaction
536
559
  * @returns Promise resolving to PermissionGrantResult with parsed events
537
560
  */
538
- async submitSignedGrantWithEvents(typedData, signature) {
539
- const txResult = await this.submitSignedGrant(typedData, signature);
561
+ async submitSignedGrantWithEvents(typedData, signature, options) {
562
+ const txResult = await this.submitSignedGrant(
563
+ typedData,
564
+ signature,
565
+ options
566
+ );
540
567
  if (!this.context.waitForTransactionEvents) {
541
568
  throw new BlockchainError("waitForTransactionEvents not configured");
542
569
  }
@@ -568,8 +595,12 @@ class PermissionsController extends BaseController {
568
595
  * @param grantFile - The pre-created grant file object
569
596
  * @returns Promise resolving to PermissionGrantResult with parsed events
570
597
  */
571
- async confirmGrantInternalWithEvents(params, grantFile) {
572
- const txResult = await this.confirmGrantInternal(params, grantFile);
598
+ async confirmGrantInternalWithEvents(params, grantFile, options) {
599
+ const txResult = await this.confirmGrantInternal(
600
+ params,
601
+ grantFile,
602
+ options
603
+ );
573
604
  if (!this.context.waitForTransactionEvents) {
574
605
  throw new BlockchainError("waitForTransactionEvents not configured");
575
606
  }
@@ -593,6 +624,39 @@ class PermissionsController extends BaseController {
593
624
  fileIds: event.fileIds
594
625
  };
595
626
  }
627
+ /**
628
+ * Polls the relayer for confirmation of a pending operation.
629
+ *
630
+ * @param operationId - The operation ID to poll
631
+ * @returns Promise resolving to the confirmed hash
632
+ * @throws {Error} When the operation fails or times out
633
+ * @internal
634
+ */
635
+ async pollRelayerForConfirmation(operationId, options = {}) {
636
+ const timeout = options.timeout ?? 3e4;
637
+ let interval = options.pollingInterval ?? 1e3;
638
+ const startTime = Date.now();
639
+ while (Date.now() - startTime < timeout) {
640
+ if (!this.context.relayer) {
641
+ throw new Error("Relayer not configured for polling");
642
+ }
643
+ const statusResponse = await this.context.relayer({
644
+ type: "status_check",
645
+ operationId
646
+ });
647
+ if (statusResponse.type === "confirmed") {
648
+ return { hash: statusResponse.hash };
649
+ }
650
+ if (statusResponse.type === "error") {
651
+ throw new Error(
652
+ `Operation ${operationId} failed: ${statusResponse.error}`
653
+ );
654
+ }
655
+ await new Promise((resolve) => setTimeout(resolve, interval));
656
+ interval = Math.min(interval * 1.5, 5e3);
657
+ }
658
+ throw new Error(`Operation ${operationId} timed out after ${timeout}ms`);
659
+ }
596
660
  /**
597
661
  * Submits an already-signed permission revoke transaction to the blockchain.
598
662
  *
@@ -614,7 +678,7 @@ class PermissionsController extends BaseController {
614
678
  * const result = await txHandle.waitForEvents();
615
679
  * ```
616
680
  */
617
- async submitSignedRevoke(typedData, signature) {
681
+ async submitSignedRevoke(typedData, signature, _options) {
618
682
  try {
619
683
  let hash;
620
684
  if (this.context.relayer) {
@@ -625,13 +689,23 @@ class PermissionsController extends BaseController {
625
689
  signature,
626
690
  expectedUserAddress: this.context.userAddress
627
691
  });
628
- if (response.type === "signed") {
629
- hash = response.hash;
630
- } else if (response.type === "error") {
692
+ if (response.type === "error") {
631
693
  throw new Error(`Relayer error: ${response.error}`);
694
+ }
695
+ if (response.type === "submitted") {
696
+ hash = response.hash;
697
+ } else if (response.type === "pending") {
698
+ const pollResult = await this.pollRelayerForConfirmation(
699
+ response.operationId
700
+ );
701
+ hash = pollResult.hash;
702
+ } else if (response.type === "confirmed") {
703
+ hash = response.hash;
704
+ } else if (response.type === "signed") {
705
+ hash = response.hash;
632
706
  } else {
633
707
  throw new Error(
634
- "Invalid response from relayer: expected signed transaction"
708
+ "Invalid response from relayer: unexpected response type"
635
709
  );
636
710
  }
637
711
  } else {
@@ -679,7 +753,7 @@ class PermissionsController extends BaseController {
679
753
  * const result = await txHandle.waitForEvents();
680
754
  * ```
681
755
  */
682
- async submitSignedUntrustServer(typedData, signature) {
756
+ async submitSignedUntrustServer(typedData, signature, _options) {
683
757
  try {
684
758
  let hash;
685
759
  if (this.context.relayer) {
@@ -735,7 +809,7 @@ class PermissionsController extends BaseController {
735
809
  * @returns Promise resolving to the transaction hash
736
810
  * @throws {BlockchainError} When contract submission fails
737
811
  */
738
- async submitDirectTransaction(typedData, signature) {
812
+ async submitDirectTransaction(typedData, signature, options) {
739
813
  this.assertWallet();
740
814
  const chainId = await this.context.publicClient.getChainId();
741
815
  const DataPortabilityPermissionsAddress = getContractAddress(
@@ -767,7 +841,8 @@ class PermissionsController extends BaseController {
767
841
  functionName: "addPermission",
768
842
  args: [permissionInput, formattedSignature],
769
843
  account,
770
- chain: this.context.walletClient?.chain ?? null
844
+ chain: this.context.walletClient?.chain ?? null,
845
+ ...this.spreadTransactionOptions(options)
771
846
  });
772
847
  const { tx } = await import("../utils/transactionHelpers");
773
848
  return tx({
@@ -866,7 +941,7 @@ class PermissionsController extends BaseController {
866
941
  args: [params.permissionId],
867
942
  account,
868
943
  chain: this.context.walletClient?.chain ?? null,
869
- ...options?.gasLimit && { gas: options.gasLimit },
944
+ ...options?.gas && { gas: options.gas },
870
945
  ...options?.nonce && { nonce: options.nonce },
871
946
  // Use EIP-1559 if available, otherwise fall back to legacy gasPrice
872
947
  ...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
@@ -1293,7 +1368,9 @@ class PermissionsController extends BaseController {
1293
1368
  * ```
1294
1369
  */
1295
1370
  async getUserPermissionGrantsOnChain(options = {}) {
1296
- const { limit = 50, subgraphUrl } = options;
1371
+ const { limit = 50, fetchAll = false, subgraphUrl } = options;
1372
+ const pageSize = fetchAll ? 100 : limit;
1373
+ const maxResults = fetchAll ? 1e4 : limit;
1297
1374
  try {
1298
1375
  const userAddress = this.context.userAddress;
1299
1376
  const graphqlEndpoint = subgraphUrl ?? this.context.subgraphUrl;
@@ -1303,10 +1380,10 @@ class PermissionsController extends BaseController {
1303
1380
  );
1304
1381
  }
1305
1382
  const query = `
1306
- query GetUserPermissions($userId: ID!) {
1383
+ query GetUserPermissions($userId: ID!, $first: Int!, $skip: Int!) {
1307
1384
  user(id: $userId) {
1308
1385
  id
1309
- permissions {
1386
+ permissions(first: $first, skip: $skip, orderBy: addedAtBlock, orderDirection: desc) {
1310
1387
  id
1311
1388
  grant
1312
1389
  nonce
@@ -1324,34 +1401,82 @@ class PermissionsController extends BaseController {
1324
1401
  }
1325
1402
  }
1326
1403
  `;
1327
- const response = await fetch(graphqlEndpoint, {
1328
- method: "POST",
1329
- headers: {
1330
- "Content-Type": "application/json"
1331
- },
1332
- body: JSON.stringify({
1333
- query,
1334
- variables: {
1335
- userId: userAddress.toLowerCase()
1404
+ const allPermissions = [];
1405
+ let currentOffset = 0;
1406
+ if (!fetchAll) {
1407
+ const response = await fetch(graphqlEndpoint, {
1408
+ method: "POST",
1409
+ headers: {
1410
+ "Content-Type": "application/json"
1411
+ },
1412
+ body: JSON.stringify({
1413
+ query,
1414
+ variables: {
1415
+ userId: userAddress.toLowerCase(),
1416
+ first: limit,
1417
+ skip: 0
1418
+ }
1419
+ })
1420
+ });
1421
+ if (!response.ok) {
1422
+ throw new BlockchainError(
1423
+ `Subgraph request failed: ${response.status} ${response.statusText}`
1424
+ );
1425
+ }
1426
+ const result = await response.json();
1427
+ if (result.errors) {
1428
+ throw new BlockchainError(
1429
+ `Subgraph errors: ${result.errors.map((e) => e.message).join(", ")}`
1430
+ );
1431
+ }
1432
+ const userData = result.data?.user;
1433
+ if (!userData?.permissions?.length) {
1434
+ return [];
1435
+ }
1436
+ allPermissions.push(...userData.permissions);
1437
+ } else {
1438
+ while (allPermissions.length < maxResults) {
1439
+ const currentLimit = Math.min(
1440
+ pageSize,
1441
+ maxResults - allPermissions.length
1442
+ );
1443
+ const response = await fetch(graphqlEndpoint, {
1444
+ method: "POST",
1445
+ headers: {
1446
+ "Content-Type": "application/json"
1447
+ },
1448
+ body: JSON.stringify({
1449
+ query,
1450
+ variables: {
1451
+ userId: userAddress.toLowerCase(),
1452
+ first: currentLimit,
1453
+ skip: currentOffset
1454
+ }
1455
+ })
1456
+ });
1457
+ if (!response.ok) {
1458
+ throw new BlockchainError(
1459
+ `Subgraph request failed: ${response.status} ${response.statusText}`
1460
+ );
1336
1461
  }
1337
- })
1338
- });
1339
- if (!response.ok) {
1340
- throw new BlockchainError(
1341
- `Subgraph request failed: ${response.status} ${response.statusText}`
1342
- );
1343
- }
1344
- const result = await response.json();
1345
- if (result.errors) {
1346
- throw new BlockchainError(
1347
- `Subgraph errors: ${result.errors.map((e) => e.message).join(", ")}`
1348
- );
1349
- }
1350
- const userData = result.data?.user;
1351
- if (!userData?.permissions?.length) {
1352
- return [];
1462
+ const result = await response.json();
1463
+ if (result.errors) {
1464
+ throw new BlockchainError(
1465
+ `Subgraph errors: ${result.errors.map((e) => e.message).join(", ")}`
1466
+ );
1467
+ }
1468
+ const userData = result.data?.user;
1469
+ if (!userData?.permissions?.length) {
1470
+ break;
1471
+ }
1472
+ allPermissions.push(...userData.permissions);
1473
+ if (userData.permissions.length < currentLimit) {
1474
+ break;
1475
+ }
1476
+ currentOffset += userData.permissions.length;
1477
+ }
1353
1478
  }
1354
- const onChainGrants = userData.permissions.slice(0, limit).map(
1479
+ const onChainGrants = allPermissions.map(
1355
1480
  (permission) => ({
1356
1481
  id: BigInt(permission.id),
1357
1482
  grantUrl: permission.grant,
@@ -1703,7 +1828,7 @@ class PermissionsController extends BaseController {
1703
1828
  args: [BigInt(params.serverId)],
1704
1829
  account,
1705
1830
  chain: this.context.walletClient?.chain ?? null,
1706
- ...options?.gasLimit && { gas: options.gasLimit },
1831
+ ...options?.gas && { gas: options.gas },
1707
1832
  ...options?.nonce && { nonce: options.nonce },
1708
1833
  // Use EIP-1559 if available, otherwise fall back to legacy gasPrice
1709
1834
  ...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
@@ -2298,7 +2423,7 @@ class PermissionsController extends BaseController {
2298
2423
  * @param signature - The cryptographic signature for the transaction
2299
2424
  * @returns Promise resolving to the transaction hash
2300
2425
  */
2301
- async submitTrustServerTransaction(trustServerInput, signature) {
2426
+ async submitTrustServerTransaction(trustServerInput, signature, options) {
2302
2427
  this.assertWallet();
2303
2428
  const chainId = await this.context.walletClient.getChainId();
2304
2429
  const DataPortabilityServersAddress = getContractAddress(
@@ -2319,7 +2444,8 @@ class PermissionsController extends BaseController {
2319
2444
  formattedSignature
2320
2445
  ],
2321
2446
  account: this.context.walletClient?.account ?? this.context.userAddress,
2322
- chain: this.context.walletClient?.chain ?? null
2447
+ chain: this.context.walletClient?.chain ?? null,
2448
+ ...this.spreadTransactionOptions(options)
2323
2449
  });
2324
2450
  return txHash;
2325
2451
  }
@@ -2356,7 +2482,7 @@ class PermissionsController extends BaseController {
2356
2482
  * @param signature - The cryptographic signature authorizing the untrust
2357
2483
  * @returns Promise resolving to the transaction hash
2358
2484
  */
2359
- async submitSignedUntrustTransaction(typedData, signature) {
2485
+ async submitSignedUntrustTransaction(typedData, signature, _options) {
2360
2486
  this.assertWallet();
2361
2487
  const chainId = await this.context.walletClient.getChainId();
2362
2488
  const DataPortabilityServersAddress = getContractAddress(
@@ -2426,15 +2552,7 @@ class PermissionsController extends BaseController {
2426
2552
  args: [ownerAddress, granteeAddress, params.publicKey],
2427
2553
  account,
2428
2554
  chain: this.context.walletClient?.chain ?? null,
2429
- ...options?.gasLimit && { gas: options.gasLimit },
2430
- ...options?.nonce && { nonce: options.nonce },
2431
- // Use EIP-1559 if available, otherwise fall back to legacy gasPrice
2432
- ...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
2433
- ...options.maxFeePerGas && { maxFeePerGas: options.maxFeePerGas },
2434
- ...options.maxPriorityFeePerGas && {
2435
- maxPriorityFeePerGas: options.maxPriorityFeePerGas
2436
- }
2437
- } : options?.gasPrice && { gasPrice: options.gasPrice }
2555
+ ...this.spreadTransactionOptions(options)
2438
2556
  });
2439
2557
  const { tx } = await import("../utils/transactionHelpers");
2440
2558
  return tx({
@@ -3372,7 +3490,7 @@ class PermissionsController extends BaseController {
3372
3490
  args: [serverId, url],
3373
3491
  chain: this.context.walletClient?.chain,
3374
3492
  account,
3375
- ...options?.gasLimit && { gas: options.gasLimit },
3493
+ ...options?.gas && { gas: options.gas },
3376
3494
  ...options?.nonce && { nonce: options.nonce },
3377
3495
  // Use EIP-1559 if available, otherwise fall back to legacy gasPrice
3378
3496
  ...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
@@ -3578,7 +3696,7 @@ class PermissionsController extends BaseController {
3578
3696
  * @throws {BlockchainError} When permission addition fails
3579
3697
  * @throws {NetworkError} When network communication fails
3580
3698
  */
3581
- async submitSignedAddPermission(typedData, signature) {
3699
+ async submitSignedAddPermission(typedData, signature, options) {
3582
3700
  this.assertWallet();
3583
3701
  try {
3584
3702
  let hash;
@@ -3601,7 +3719,8 @@ class PermissionsController extends BaseController {
3601
3719
  } else {
3602
3720
  hash = await this.submitDirectAddPermissionTransaction(
3603
3721
  typedData,
3604
- signature
3722
+ signature,
3723
+ options
3605
3724
  );
3606
3725
  }
3607
3726
  const account = this.context.walletClient?.account ?? this.context.userAddress;
@@ -3832,7 +3951,7 @@ class PermissionsController extends BaseController {
3832
3951
  args: [permissionId],
3833
3952
  chain: this.context.walletClient?.chain,
3834
3953
  account,
3835
- ...options?.gasLimit && { gas: options.gasLimit },
3954
+ ...options?.gas && { gas: options.gas },
3836
3955
  ...options?.nonce && { nonce: options.nonce },
3837
3956
  // Use EIP-1559 if available, otherwise fall back to legacy gasPrice
3838
3957
  ...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
@@ -3865,7 +3984,7 @@ class PermissionsController extends BaseController {
3865
3984
  * @param signature - The cryptographic signature authorizing the transaction
3866
3985
  * @returns Promise resolving to the transaction hash
3867
3986
  */
3868
- async submitDirectAddPermissionTransaction(typedData, signature) {
3987
+ async submitDirectAddPermissionTransaction(typedData, signature, options) {
3869
3988
  this.assertWallet();
3870
3989
  const chainId = await this.context.walletClient.getChainId();
3871
3990
  const DataPortabilityPermissionsAddress = getContractAddress(
@@ -3886,7 +4005,8 @@ class PermissionsController extends BaseController {
3886
4005
  functionName: "addPermission",
3887
4006
  args: [permissionInput, formattedSignature],
3888
4007
  account: this.context.walletClient?.account ?? this.context.userAddress,
3889
- chain: this.context.walletClient?.chain ?? null
4008
+ chain: this.context.walletClient?.chain ?? null,
4009
+ ...this.spreadTransactionOptions(options)
3890
4010
  });
3891
4011
  return hash;
3892
4012
  }
@@ -3921,22 +4041,11 @@ class PermissionsController extends BaseController {
3921
4041
  address: DataPortabilityPermissionsAddress,
3922
4042
  abi: DataPortabilityPermissionsAbi,
3923
4043
  functionName: "addServerFilesAndPermissions",
3924
- // @ts-expect-error - Viem's type inference for nested Permission[][] arrays is incompatible with our Permission type
3925
4044
  args: [serverFilesAndPermissionInput, formattedSignature],
3926
4045
  account: this.context.walletClient?.account ?? this.context.userAddress,
3927
4046
  chain: this.context.walletClient?.chain ?? null,
3928
- ...options?.gasLimit && { gas: options.gasLimit },
3929
- ...options?.nonce && { nonce: options.nonce },
3930
4047
  ...options?.value && { value: options.value },
3931
- // Use EIP-1559 if available, otherwise fall back to legacy gasPrice
3932
- ...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
3933
- ...options.maxFeePerGas && {
3934
- maxFeePerGas: options.maxFeePerGas
3935
- },
3936
- ...options.maxPriorityFeePerGas && {
3937
- maxPriorityFeePerGas: options.maxPriorityFeePerGas
3938
- }
3939
- } : options?.gasPrice && { gasPrice: options.gasPrice }
4048
+ ...this.spreadTransactionOptions(options)
3940
4049
  });
3941
4050
  return hash;
3942
4051
  }