@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
@@ -80,10 +80,14 @@ class PermissionsController extends import_base.BaseController {
80
80
  * await vana.permissions.revoke({ permissionId: result.permissionId });
81
81
  * ```
82
82
  */
83
- async grant(params) {
83
+ async grant(params, options) {
84
84
  this.assertWallet();
85
85
  const { typedData, signature } = await this.createAndSign(params);
86
- const result = await this.submitSignedGrantWithEvents(typedData, signature);
86
+ const result = await this.submitSignedGrantWithEvents(
87
+ typedData,
88
+ signature,
89
+ options
90
+ );
87
91
  return result;
88
92
  }
89
93
  /**
@@ -111,10 +115,10 @@ class PermissionsController extends import_base.BaseController {
111
115
  * console.log(`Permission ID: ${eventData.permissionId}`);
112
116
  * ```
113
117
  */
114
- async submitPermissionGrant(params) {
118
+ async submitPermissionGrant(params, options) {
115
119
  this.assertWallet();
116
120
  const { typedData, signature } = await this.createAndSign(params);
117
- return await this.submitSignedGrant(typedData, signature);
121
+ return await this.submitSignedGrant(typedData, signature, options);
118
122
  }
119
123
  /**
120
124
  * Prepares a permission grant with preview before signing.
@@ -141,7 +145,7 @@ class PermissionsController extends import_base.BaseController {
141
145
  * const transactionHash = await confirm();
142
146
  * ```
143
147
  */
144
- async prepareGrant(params) {
148
+ async prepareGrant(params, options) {
145
149
  this.assertWallet();
146
150
  try {
147
151
  const grantFile = (0, import_grantFiles.createGrantFile)(params);
@@ -149,7 +153,11 @@ class PermissionsController extends import_base.BaseController {
149
153
  return {
150
154
  preview: grantFile,
151
155
  confirm: async () => {
152
- return await this.confirmGrantInternalWithEvents(params, grantFile);
156
+ return await this.confirmGrantInternalWithEvents(
157
+ params,
158
+ grantFile,
159
+ options
160
+ );
153
161
  }
154
162
  };
155
163
  } catch (error) {
@@ -181,7 +189,7 @@ class PermissionsController extends import_base.BaseController {
181
189
  * @throws {NetworkError} When IPFS upload fails
182
190
  * @throws {SignatureError} When user rejects the signature
183
191
  */
184
- async confirmGrantInternal(params, grantFile) {
192
+ async confirmGrantInternal(params, grantFile, options) {
185
193
  try {
186
194
  let { grantUrl } = params;
187
195
  console.debug("\u{1F50D} Debug - Grant URL from params:", grantUrl);
@@ -206,7 +214,7 @@ class PermissionsController extends import_base.BaseController {
206
214
  if (response.type === "error") {
207
215
  throw new Error(response.error);
208
216
  }
209
- if (response.type === "direct" && typeof response.result === "object" && "url" in response.result) {
217
+ if (response.type === "direct" && typeof response.result === "object" && response.result !== null && "url" in response.result) {
210
218
  grantUrl = response.result.url;
211
219
  } else {
212
220
  throw new Error("Invalid response from relayer for grant storage");
@@ -242,7 +250,7 @@ class PermissionsController extends import_base.BaseController {
242
250
  nonce
243
251
  });
244
252
  const signature = await this.signTypedData(typedData);
245
- return await this.submitSignedGrant(typedData, signature);
253
+ return await this.submitSignedGrant(typedData, signature, options);
246
254
  } catch (error) {
247
255
  if (error instanceof Error) {
248
256
  if (error instanceof import_errors.RelayerError || error instanceof import_errors.UserRejectedRequestError || error instanceof import_errors.SerializationError || error instanceof import_errors.SignatureError || error instanceof import_errors.NetworkError || error instanceof import_errors.NonceError) {
@@ -314,7 +322,7 @@ class PermissionsController extends import_base.BaseController {
314
322
  if (response.type === "error") {
315
323
  throw new Error(response.error);
316
324
  }
317
- if (response.type === "direct" && typeof response.result === "object" && "url" in response.result) {
325
+ if (response.type === "direct" && typeof response.result === "object" && response.result !== null && "url" in response.result) {
318
326
  grantUrl = response.result.url;
319
327
  } else {
320
328
  throw new Error("Invalid response from relayer for grant storage");
@@ -387,7 +395,7 @@ class PermissionsController extends import_base.BaseController {
387
395
  * );
388
396
  * ```
389
397
  */
390
- async submitSignedGrant(typedData, signature) {
398
+ async submitSignedGrant(typedData, signature, options) {
391
399
  try {
392
400
  console.debug(
393
401
  "\u{1F50D} Debug - submitSignedGrant called with typed data:",
@@ -405,26 +413,40 @@ class PermissionsController extends import_base.BaseController {
405
413
  signature,
406
414
  expectedUserAddress: this.context.userAddress
407
415
  });
408
- let hash;
409
- if (response.type === "signed") {
410
- hash = response.hash;
411
- } else if (response.type === "error") {
416
+ if (response.type === "error") {
412
417
  throw new Error(`Relayer error: ${response.error}`);
418
+ }
419
+ let finalHash;
420
+ if (response.type === "submitted") {
421
+ finalHash = response.hash;
422
+ } else if (response.type === "pending") {
423
+ const pollResult = await this.pollRelayerForConfirmation(
424
+ response.operationId
425
+ );
426
+ finalHash = pollResult.hash;
427
+ } else if (response.type === "confirmed") {
428
+ finalHash = response.hash;
429
+ } else if (response.type === "signed") {
430
+ finalHash = response.hash;
413
431
  } else {
414
432
  throw new Error(
415
- "Invalid response from relayer: expected signed transaction"
433
+ "Invalid response from relayer: unexpected response type"
416
434
  );
417
435
  }
418
436
  const account = this.context.walletClient?.account ?? this.context.userAddress;
419
437
  const { tx } = await import("../utils/transactionHelpers");
420
438
  return tx({
421
- hash,
439
+ hash: finalHash,
422
440
  from: typeof account === "string" ? account : account.address,
423
441
  contract: "DataPortabilityPermissions",
424
442
  fn: "addPermission"
425
443
  });
426
444
  } else {
427
- return await this.submitDirectTransaction(typedData, signature);
445
+ return await this.submitDirectTransaction(
446
+ typedData,
447
+ signature,
448
+ options
449
+ );
428
450
  }
429
451
  } catch (error) {
430
452
  if (error instanceof import_errors.RelayerError || error instanceof import_errors.NetworkError || error instanceof import_errors.UserRejectedRequestError || error instanceof import_errors.SignatureError || error instanceof import_errors.NonceError) {
@@ -457,7 +479,7 @@ class PermissionsController extends import_base.BaseController {
457
479
  * const result = await txHandle.waitForEvents();
458
480
  * ```
459
481
  */
460
- async submitSignedTrustServer(typedData, signature) {
482
+ async submitSignedTrustServer(typedData, signature, options) {
461
483
  try {
462
484
  const trustServerInput = {
463
485
  nonce: BigInt(typedData.message.nonce),
@@ -465,7 +487,8 @@ class PermissionsController extends import_base.BaseController {
465
487
  };
466
488
  const hash = await this.submitTrustServerTransaction(
467
489
  trustServerInput,
468
- signature
490
+ signature,
491
+ options
469
492
  );
470
493
  const account = this.context.userAddress;
471
494
  const { tx } = await import("../utils/transactionHelpers");
@@ -520,7 +543,7 @@ class PermissionsController extends import_base.BaseController {
520
543
  * const result = await txHandle.waitForEvents();
521
544
  * ```
522
545
  */
523
- async submitSignedAddAndTrustServer(typedData, signature) {
546
+ async submitSignedAddAndTrustServer(typedData, signature, _options) {
524
547
  try {
525
548
  const addAndTrustServerInput = {
526
549
  nonce: BigInt(typedData.message.nonce),
@@ -558,8 +581,12 @@ class PermissionsController extends import_base.BaseController {
558
581
  * @param signature - The user's signature authorizing the transaction
559
582
  * @returns Promise resolving to PermissionGrantResult with parsed events
560
583
  */
561
- async submitSignedGrantWithEvents(typedData, signature) {
562
- const txResult = await this.submitSignedGrant(typedData, signature);
584
+ async submitSignedGrantWithEvents(typedData, signature, options) {
585
+ const txResult = await this.submitSignedGrant(
586
+ typedData,
587
+ signature,
588
+ options
589
+ );
563
590
  if (!this.context.waitForTransactionEvents) {
564
591
  throw new import_errors.BlockchainError("waitForTransactionEvents not configured");
565
592
  }
@@ -591,8 +618,12 @@ class PermissionsController extends import_base.BaseController {
591
618
  * @param grantFile - The pre-created grant file object
592
619
  * @returns Promise resolving to PermissionGrantResult with parsed events
593
620
  */
594
- async confirmGrantInternalWithEvents(params, grantFile) {
595
- const txResult = await this.confirmGrantInternal(params, grantFile);
621
+ async confirmGrantInternalWithEvents(params, grantFile, options) {
622
+ const txResult = await this.confirmGrantInternal(
623
+ params,
624
+ grantFile,
625
+ options
626
+ );
596
627
  if (!this.context.waitForTransactionEvents) {
597
628
  throw new import_errors.BlockchainError("waitForTransactionEvents not configured");
598
629
  }
@@ -616,6 +647,39 @@ class PermissionsController extends import_base.BaseController {
616
647
  fileIds: event.fileIds
617
648
  };
618
649
  }
650
+ /**
651
+ * Polls the relayer for confirmation of a pending operation.
652
+ *
653
+ * @param operationId - The operation ID to poll
654
+ * @returns Promise resolving to the confirmed hash
655
+ * @throws {Error} When the operation fails or times out
656
+ * @internal
657
+ */
658
+ async pollRelayerForConfirmation(operationId, options = {}) {
659
+ const timeout = options.timeout ?? 3e4;
660
+ let interval = options.pollingInterval ?? 1e3;
661
+ const startTime = Date.now();
662
+ while (Date.now() - startTime < timeout) {
663
+ if (!this.context.relayer) {
664
+ throw new Error("Relayer not configured for polling");
665
+ }
666
+ const statusResponse = await this.context.relayer({
667
+ type: "status_check",
668
+ operationId
669
+ });
670
+ if (statusResponse.type === "confirmed") {
671
+ return { hash: statusResponse.hash };
672
+ }
673
+ if (statusResponse.type === "error") {
674
+ throw new Error(
675
+ `Operation ${operationId} failed: ${statusResponse.error}`
676
+ );
677
+ }
678
+ await new Promise((resolve) => setTimeout(resolve, interval));
679
+ interval = Math.min(interval * 1.5, 5e3);
680
+ }
681
+ throw new Error(`Operation ${operationId} timed out after ${timeout}ms`);
682
+ }
619
683
  /**
620
684
  * Submits an already-signed permission revoke transaction to the blockchain.
621
685
  *
@@ -637,7 +701,7 @@ class PermissionsController extends import_base.BaseController {
637
701
  * const result = await txHandle.waitForEvents();
638
702
  * ```
639
703
  */
640
- async submitSignedRevoke(typedData, signature) {
704
+ async submitSignedRevoke(typedData, signature, _options) {
641
705
  try {
642
706
  let hash;
643
707
  if (this.context.relayer) {
@@ -648,13 +712,23 @@ class PermissionsController extends import_base.BaseController {
648
712
  signature,
649
713
  expectedUserAddress: this.context.userAddress
650
714
  });
651
- if (response.type === "signed") {
652
- hash = response.hash;
653
- } else if (response.type === "error") {
715
+ if (response.type === "error") {
654
716
  throw new Error(`Relayer error: ${response.error}`);
717
+ }
718
+ if (response.type === "submitted") {
719
+ hash = response.hash;
720
+ } else if (response.type === "pending") {
721
+ const pollResult = await this.pollRelayerForConfirmation(
722
+ response.operationId
723
+ );
724
+ hash = pollResult.hash;
725
+ } else if (response.type === "confirmed") {
726
+ hash = response.hash;
727
+ } else if (response.type === "signed") {
728
+ hash = response.hash;
655
729
  } else {
656
730
  throw new Error(
657
- "Invalid response from relayer: expected signed transaction"
731
+ "Invalid response from relayer: unexpected response type"
658
732
  );
659
733
  }
660
734
  } else {
@@ -702,7 +776,7 @@ class PermissionsController extends import_base.BaseController {
702
776
  * const result = await txHandle.waitForEvents();
703
777
  * ```
704
778
  */
705
- async submitSignedUntrustServer(typedData, signature) {
779
+ async submitSignedUntrustServer(typedData, signature, _options) {
706
780
  try {
707
781
  let hash;
708
782
  if (this.context.relayer) {
@@ -758,7 +832,7 @@ class PermissionsController extends import_base.BaseController {
758
832
  * @returns Promise resolving to the transaction hash
759
833
  * @throws {BlockchainError} When contract submission fails
760
834
  */
761
- async submitDirectTransaction(typedData, signature) {
835
+ async submitDirectTransaction(typedData, signature, options) {
762
836
  this.assertWallet();
763
837
  const chainId = await this.context.publicClient.getChainId();
764
838
  const DataPortabilityPermissionsAddress = (0, import_addresses.getContractAddress)(
@@ -790,7 +864,8 @@ class PermissionsController extends import_base.BaseController {
790
864
  functionName: "addPermission",
791
865
  args: [permissionInput, formattedSignature],
792
866
  account,
793
- chain: this.context.walletClient?.chain ?? null
867
+ chain: this.context.walletClient?.chain ?? null,
868
+ ...this.spreadTransactionOptions(options)
794
869
  });
795
870
  const { tx } = await import("../utils/transactionHelpers");
796
871
  return tx({
@@ -889,7 +964,7 @@ class PermissionsController extends import_base.BaseController {
889
964
  args: [params.permissionId],
890
965
  account,
891
966
  chain: this.context.walletClient?.chain ?? null,
892
- ...options?.gasLimit && { gas: options.gasLimit },
967
+ ...options?.gas && { gas: options.gas },
893
968
  ...options?.nonce && { nonce: options.nonce },
894
969
  // Use EIP-1559 if available, otherwise fall back to legacy gasPrice
895
970
  ...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
@@ -1316,7 +1391,9 @@ class PermissionsController extends import_base.BaseController {
1316
1391
  * ```
1317
1392
  */
1318
1393
  async getUserPermissionGrantsOnChain(options = {}) {
1319
- const { limit = 50, subgraphUrl } = options;
1394
+ const { limit = 50, fetchAll = false, subgraphUrl } = options;
1395
+ const pageSize = fetchAll ? 100 : limit;
1396
+ const maxResults = fetchAll ? 1e4 : limit;
1320
1397
  try {
1321
1398
  const userAddress = this.context.userAddress;
1322
1399
  const graphqlEndpoint = subgraphUrl ?? this.context.subgraphUrl;
@@ -1326,10 +1403,10 @@ class PermissionsController extends import_base.BaseController {
1326
1403
  );
1327
1404
  }
1328
1405
  const query = `
1329
- query GetUserPermissions($userId: ID!) {
1406
+ query GetUserPermissions($userId: ID!, $first: Int!, $skip: Int!) {
1330
1407
  user(id: $userId) {
1331
1408
  id
1332
- permissions {
1409
+ permissions(first: $first, skip: $skip, orderBy: addedAtBlock, orderDirection: desc) {
1333
1410
  id
1334
1411
  grant
1335
1412
  nonce
@@ -1347,34 +1424,82 @@ class PermissionsController extends import_base.BaseController {
1347
1424
  }
1348
1425
  }
1349
1426
  `;
1350
- const response = await fetch(graphqlEndpoint, {
1351
- method: "POST",
1352
- headers: {
1353
- "Content-Type": "application/json"
1354
- },
1355
- body: JSON.stringify({
1356
- query,
1357
- variables: {
1358
- userId: userAddress.toLowerCase()
1427
+ const allPermissions = [];
1428
+ let currentOffset = 0;
1429
+ if (!fetchAll) {
1430
+ const response = await fetch(graphqlEndpoint, {
1431
+ method: "POST",
1432
+ headers: {
1433
+ "Content-Type": "application/json"
1434
+ },
1435
+ body: JSON.stringify({
1436
+ query,
1437
+ variables: {
1438
+ userId: userAddress.toLowerCase(),
1439
+ first: limit,
1440
+ skip: 0
1441
+ }
1442
+ })
1443
+ });
1444
+ if (!response.ok) {
1445
+ throw new import_errors.BlockchainError(
1446
+ `Subgraph request failed: ${response.status} ${response.statusText}`
1447
+ );
1448
+ }
1449
+ const result = await response.json();
1450
+ if (result.errors) {
1451
+ throw new import_errors.BlockchainError(
1452
+ `Subgraph errors: ${result.errors.map((e) => e.message).join(", ")}`
1453
+ );
1454
+ }
1455
+ const userData = result.data?.user;
1456
+ if (!userData?.permissions?.length) {
1457
+ return [];
1458
+ }
1459
+ allPermissions.push(...userData.permissions);
1460
+ } else {
1461
+ while (allPermissions.length < maxResults) {
1462
+ const currentLimit = Math.min(
1463
+ pageSize,
1464
+ maxResults - allPermissions.length
1465
+ );
1466
+ const response = await fetch(graphqlEndpoint, {
1467
+ method: "POST",
1468
+ headers: {
1469
+ "Content-Type": "application/json"
1470
+ },
1471
+ body: JSON.stringify({
1472
+ query,
1473
+ variables: {
1474
+ userId: userAddress.toLowerCase(),
1475
+ first: currentLimit,
1476
+ skip: currentOffset
1477
+ }
1478
+ })
1479
+ });
1480
+ if (!response.ok) {
1481
+ throw new import_errors.BlockchainError(
1482
+ `Subgraph request failed: ${response.status} ${response.statusText}`
1483
+ );
1359
1484
  }
1360
- })
1361
- });
1362
- if (!response.ok) {
1363
- throw new import_errors.BlockchainError(
1364
- `Subgraph request failed: ${response.status} ${response.statusText}`
1365
- );
1366
- }
1367
- const result = await response.json();
1368
- if (result.errors) {
1369
- throw new import_errors.BlockchainError(
1370
- `Subgraph errors: ${result.errors.map((e) => e.message).join(", ")}`
1371
- );
1372
- }
1373
- const userData = result.data?.user;
1374
- if (!userData?.permissions?.length) {
1375
- return [];
1485
+ const result = await response.json();
1486
+ if (result.errors) {
1487
+ throw new import_errors.BlockchainError(
1488
+ `Subgraph errors: ${result.errors.map((e) => e.message).join(", ")}`
1489
+ );
1490
+ }
1491
+ const userData = result.data?.user;
1492
+ if (!userData?.permissions?.length) {
1493
+ break;
1494
+ }
1495
+ allPermissions.push(...userData.permissions);
1496
+ if (userData.permissions.length < currentLimit) {
1497
+ break;
1498
+ }
1499
+ currentOffset += userData.permissions.length;
1500
+ }
1376
1501
  }
1377
- const onChainGrants = userData.permissions.slice(0, limit).map(
1502
+ const onChainGrants = allPermissions.map(
1378
1503
  (permission) => ({
1379
1504
  id: BigInt(permission.id),
1380
1505
  grantUrl: permission.grant,
@@ -1726,7 +1851,7 @@ class PermissionsController extends import_base.BaseController {
1726
1851
  args: [BigInt(params.serverId)],
1727
1852
  account,
1728
1853
  chain: this.context.walletClient?.chain ?? null,
1729
- ...options?.gasLimit && { gas: options.gasLimit },
1854
+ ...options?.gas && { gas: options.gas },
1730
1855
  ...options?.nonce && { nonce: options.nonce },
1731
1856
  // Use EIP-1559 if available, otherwise fall back to legacy gasPrice
1732
1857
  ...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
@@ -2321,7 +2446,7 @@ class PermissionsController extends import_base.BaseController {
2321
2446
  * @param signature - The cryptographic signature for the transaction
2322
2447
  * @returns Promise resolving to the transaction hash
2323
2448
  */
2324
- async submitTrustServerTransaction(trustServerInput, signature) {
2449
+ async submitTrustServerTransaction(trustServerInput, signature, options) {
2325
2450
  this.assertWallet();
2326
2451
  const chainId = await this.context.walletClient.getChainId();
2327
2452
  const DataPortabilityServersAddress = (0, import_addresses.getContractAddress)(
@@ -2342,7 +2467,8 @@ class PermissionsController extends import_base.BaseController {
2342
2467
  formattedSignature
2343
2468
  ],
2344
2469
  account: this.context.walletClient?.account ?? this.context.userAddress,
2345
- chain: this.context.walletClient?.chain ?? null
2470
+ chain: this.context.walletClient?.chain ?? null,
2471
+ ...this.spreadTransactionOptions(options)
2346
2472
  });
2347
2473
  return txHash;
2348
2474
  }
@@ -2379,7 +2505,7 @@ class PermissionsController extends import_base.BaseController {
2379
2505
  * @param signature - The cryptographic signature authorizing the untrust
2380
2506
  * @returns Promise resolving to the transaction hash
2381
2507
  */
2382
- async submitSignedUntrustTransaction(typedData, signature) {
2508
+ async submitSignedUntrustTransaction(typedData, signature, _options) {
2383
2509
  this.assertWallet();
2384
2510
  const chainId = await this.context.walletClient.getChainId();
2385
2511
  const DataPortabilityServersAddress = (0, import_addresses.getContractAddress)(
@@ -2449,15 +2575,7 @@ class PermissionsController extends import_base.BaseController {
2449
2575
  args: [ownerAddress, granteeAddress, params.publicKey],
2450
2576
  account,
2451
2577
  chain: this.context.walletClient?.chain ?? null,
2452
- ...options?.gasLimit && { gas: options.gasLimit },
2453
- ...options?.nonce && { nonce: options.nonce },
2454
- // Use EIP-1559 if available, otherwise fall back to legacy gasPrice
2455
- ...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
2456
- ...options.maxFeePerGas && { maxFeePerGas: options.maxFeePerGas },
2457
- ...options.maxPriorityFeePerGas && {
2458
- maxPriorityFeePerGas: options.maxPriorityFeePerGas
2459
- }
2460
- } : options?.gasPrice && { gasPrice: options.gasPrice }
2578
+ ...this.spreadTransactionOptions(options)
2461
2579
  });
2462
2580
  const { tx } = await import("../utils/transactionHelpers");
2463
2581
  return tx({
@@ -3395,7 +3513,7 @@ class PermissionsController extends import_base.BaseController {
3395
3513
  args: [serverId, url],
3396
3514
  chain: this.context.walletClient?.chain,
3397
3515
  account,
3398
- ...options?.gasLimit && { gas: options.gasLimit },
3516
+ ...options?.gas && { gas: options.gas },
3399
3517
  ...options?.nonce && { nonce: options.nonce },
3400
3518
  // Use EIP-1559 if available, otherwise fall back to legacy gasPrice
3401
3519
  ...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
@@ -3601,7 +3719,7 @@ class PermissionsController extends import_base.BaseController {
3601
3719
  * @throws {BlockchainError} When permission addition fails
3602
3720
  * @throws {NetworkError} When network communication fails
3603
3721
  */
3604
- async submitSignedAddPermission(typedData, signature) {
3722
+ async submitSignedAddPermission(typedData, signature, options) {
3605
3723
  this.assertWallet();
3606
3724
  try {
3607
3725
  let hash;
@@ -3624,7 +3742,8 @@ class PermissionsController extends import_base.BaseController {
3624
3742
  } else {
3625
3743
  hash = await this.submitDirectAddPermissionTransaction(
3626
3744
  typedData,
3627
- signature
3745
+ signature,
3746
+ options
3628
3747
  );
3629
3748
  }
3630
3749
  const account = this.context.walletClient?.account ?? this.context.userAddress;
@@ -3855,7 +3974,7 @@ class PermissionsController extends import_base.BaseController {
3855
3974
  args: [permissionId],
3856
3975
  chain: this.context.walletClient?.chain,
3857
3976
  account,
3858
- ...options?.gasLimit && { gas: options.gasLimit },
3977
+ ...options?.gas && { gas: options.gas },
3859
3978
  ...options?.nonce && { nonce: options.nonce },
3860
3979
  // Use EIP-1559 if available, otherwise fall back to legacy gasPrice
3861
3980
  ...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
@@ -3888,7 +4007,7 @@ class PermissionsController extends import_base.BaseController {
3888
4007
  * @param signature - The cryptographic signature authorizing the transaction
3889
4008
  * @returns Promise resolving to the transaction hash
3890
4009
  */
3891
- async submitDirectAddPermissionTransaction(typedData, signature) {
4010
+ async submitDirectAddPermissionTransaction(typedData, signature, options) {
3892
4011
  this.assertWallet();
3893
4012
  const chainId = await this.context.walletClient.getChainId();
3894
4013
  const DataPortabilityPermissionsAddress = (0, import_addresses.getContractAddress)(
@@ -3909,7 +4028,8 @@ class PermissionsController extends import_base.BaseController {
3909
4028
  functionName: "addPermission",
3910
4029
  args: [permissionInput, formattedSignature],
3911
4030
  account: this.context.walletClient?.account ?? this.context.userAddress,
3912
- chain: this.context.walletClient?.chain ?? null
4031
+ chain: this.context.walletClient?.chain ?? null,
4032
+ ...this.spreadTransactionOptions(options)
3913
4033
  });
3914
4034
  return hash;
3915
4035
  }
@@ -3944,22 +4064,11 @@ class PermissionsController extends import_base.BaseController {
3944
4064
  address: DataPortabilityPermissionsAddress,
3945
4065
  abi: DataPortabilityPermissionsAbi,
3946
4066
  functionName: "addServerFilesAndPermissions",
3947
- // @ts-expect-error - Viem's type inference for nested Permission[][] arrays is incompatible with our Permission type
3948
4067
  args: [serverFilesAndPermissionInput, formattedSignature],
3949
4068
  account: this.context.walletClient?.account ?? this.context.userAddress,
3950
4069
  chain: this.context.walletClient?.chain ?? null,
3951
- ...options?.gasLimit && { gas: options.gasLimit },
3952
- ...options?.nonce && { nonce: options.nonce },
3953
4070
  ...options?.value && { value: options.value },
3954
- // Use EIP-1559 if available, otherwise fall back to legacy gasPrice
3955
- ...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
3956
- ...options.maxFeePerGas && {
3957
- maxFeePerGas: options.maxFeePerGas
3958
- },
3959
- ...options.maxPriorityFeePerGas && {
3960
- maxPriorityFeePerGas: options.maxPriorityFeePerGas
3961
- }
3962
- } : options?.gasPrice && { gasPrice: options.gasPrice }
4071
+ ...this.spreadTransactionOptions(options)
3963
4072
  });
3964
4073
  return hash;
3965
4074
  }