@opendatalabs/vana-sdk 0.1.0-alpha.f0290d0 → 0.1.0-alpha.ffe4659

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 (50) hide show
  1. package/README.md +42 -0
  2. package/dist/browser-DY8XDblx.d.ts +241 -0
  3. package/dist/browser.d.ts +1 -0
  4. package/dist/browser.js +309 -0
  5. package/dist/browser.js.map +1 -0
  6. package/dist/chains.browser.cjs +2 -2
  7. package/dist/chains.browser.cjs.map +1 -1
  8. package/dist/chains.browser.js +2 -2
  9. package/dist/chains.browser.js.map +1 -1
  10. package/dist/chains.cjs +2 -2
  11. package/dist/chains.cjs.map +1 -1
  12. package/dist/chains.js +2 -2
  13. package/dist/chains.js.map +1 -1
  14. package/dist/chains.node.cjs +2 -2
  15. package/dist/chains.node.cjs.map +1 -1
  16. package/dist/chains.node.js +2 -2
  17. package/dist/chains.node.js.map +1 -1
  18. package/dist/index.browser.d.ts +889 -286
  19. package/dist/index.browser.js +2187 -1246
  20. package/dist/index.browser.js.map +1 -1
  21. package/dist/index.node.cjs +2259 -1325
  22. package/dist/index.node.cjs.map +1 -1
  23. package/dist/index.node.d.cts +923 -293
  24. package/dist/index.node.d.ts +923 -293
  25. package/dist/index.node.js +2235 -1302
  26. package/dist/index.node.js.map +1 -1
  27. package/dist/node-D9-F9uEP.d.cts +238 -0
  28. package/dist/node-D9-F9uEP.d.ts +238 -0
  29. package/dist/node.cjs +348 -0
  30. package/dist/node.cjs.map +1 -0
  31. package/dist/node.d.cts +1 -0
  32. package/dist/node.d.ts +1 -0
  33. package/dist/node.js +311 -0
  34. package/dist/node.js.map +1 -0
  35. package/dist/platform.browser.d.ts +3 -236
  36. package/dist/platform.browser.js +31 -8
  37. package/dist/platform.browser.js.map +1 -1
  38. package/dist/platform.cjs +72 -62
  39. package/dist/platform.cjs.map +1 -1
  40. package/dist/platform.d.cts +2 -1
  41. package/dist/platform.d.ts +2 -1
  42. package/dist/platform.js +72 -62
  43. package/dist/platform.js.map +1 -1
  44. package/dist/platform.node.cjs +72 -62
  45. package/dist/platform.node.cjs.map +1 -1
  46. package/dist/platform.node.d.cts +7 -236
  47. package/dist/platform.node.d.ts +7 -236
  48. package/dist/platform.node.js +72 -62
  49. package/dist/platform.node.js.map +1 -1
  50. package/package.json +17 -12
@@ -99,15 +99,35 @@ var init_error_utils = __esm({
99
99
  }
100
100
  });
101
101
 
102
+ // src/utils/lazy-import.ts
103
+ function lazyImport(importFn) {
104
+ let cached = null;
105
+ return () => {
106
+ if (!cached) {
107
+ cached = importFn().catch((err) => {
108
+ cached = null;
109
+ throw new Error("Failed to load module", { cause: err });
110
+ });
111
+ }
112
+ return cached;
113
+ };
114
+ }
115
+ var init_lazy_import = __esm({
116
+ "src/utils/lazy-import.ts"() {
117
+ "use strict";
118
+ }
119
+ });
120
+
102
121
  // src/platform/browser.ts
103
- import * as openpgp from "openpgp";
104
- var BrowserCryptoAdapter, BrowserPGPAdapter, BrowserHttpAdapter, BrowserCacheAdapter, BrowserPlatformAdapter, browserPlatformAdapter;
122
+ var getOpenPGP, BrowserCryptoAdapter, BrowserPGPAdapter, BrowserHttpAdapter, BrowserCacheAdapter, BrowserPlatformAdapter, browserPlatformAdapter;
105
123
  var init_browser = __esm({
106
124
  "src/platform/browser.ts"() {
107
125
  "use strict";
108
126
  init_crypto_utils();
109
127
  init_pgp_utils();
110
128
  init_error_utils();
129
+ init_lazy_import();
130
+ getOpenPGP = lazyImport(() => import("openpgp"));
111
131
  BrowserCryptoAdapter = class {
112
132
  async encryptWithPublicKey(data, publicKeyHex) {
113
133
  try {
@@ -196,11 +216,11 @@ var init_browser = __esm({
196
216
  }
197
217
  async encryptWithPassword(data, password) {
198
218
  try {
199
- const openpgp2 = await import("openpgp");
200
- const message = await openpgp2.createMessage({
219
+ const openpgp = await getOpenPGP();
220
+ const message = await openpgp.createMessage({
201
221
  binary: data
202
222
  });
203
- const encrypted = await openpgp2.encrypt({
223
+ const encrypted = await openpgp.encrypt({
204
224
  message,
205
225
  passwords: [password],
206
226
  format: "binary"
@@ -214,11 +234,11 @@ var init_browser = __esm({
214
234
  }
215
235
  async decryptWithPassword(encryptedData, password) {
216
236
  try {
217
- const openpgp2 = await import("openpgp");
218
- const message = await openpgp2.readMessage({
237
+ const openpgp = await getOpenPGP();
238
+ const message = await openpgp.readMessage({
219
239
  binaryMessage: encryptedData
220
240
  });
221
- const { data: decrypted } = await openpgp2.decrypt({
241
+ const { data: decrypted } = await openpgp.decrypt({
222
242
  message,
223
243
  passwords: [password],
224
244
  format: "binary"
@@ -232,6 +252,7 @@ var init_browser = __esm({
232
252
  BrowserPGPAdapter = class {
233
253
  async encrypt(data, publicKeyArmored) {
234
254
  try {
255
+ const openpgp = await getOpenPGP();
235
256
  const publicKey = await openpgp.readKey({ armoredKey: publicKeyArmored });
236
257
  const encrypted = await openpgp.encrypt({
237
258
  message: await openpgp.createMessage({ text: data }),
@@ -247,6 +268,7 @@ var init_browser = __esm({
247
268
  }
248
269
  async decrypt(encryptedData, privateKeyArmored) {
249
270
  try {
271
+ const openpgp = await getOpenPGP();
250
272
  const privateKey = await openpgp.readPrivateKey({
251
273
  armoredKey: privateKeyArmored
252
274
  });
@@ -264,6 +286,7 @@ var init_browser = __esm({
264
286
  }
265
287
  async generateKeyPair(options) {
266
288
  try {
289
+ const openpgp = await getOpenPGP();
267
290
  const keyGenParams = getPGPKeyGenParams(options);
268
291
  const { privateKey, publicKey } = await openpgp.generateKey(keyGenParams);
269
292
  return { publicKey, privateKey };
@@ -869,12 +892,486 @@ var PermissionError = class extends VanaError {
869
892
  }
870
893
  };
871
894
 
895
+ // src/utils/multicall.ts
896
+ import { encodeFunctionData, size } from "viem";
897
+
898
+ // src/config/addresses.ts
899
+ var CONTRACTS = {
900
+ // Data Portability Contracts (New Architecture)
901
+ DataPortabilityPermissions: {
902
+ addresses: {
903
+ 14800: "0xD54523048AdD05b4d734aFaE7C68324Ebb7373eF",
904
+ 1480: "0xD54523048AdD05b4d734aFaE7C68324Ebb7373eF"
905
+ }
906
+ },
907
+ DataPortabilityServers: {
908
+ addresses: {
909
+ 14800: "0x1483B1F634DBA75AeaE60da7f01A679aabd5ee2c",
910
+ 1480: "0x1483B1F634DBA75AeaE60da7f01A679aabd5ee2c"
911
+ }
912
+ },
913
+ DataPortabilityGrantees: {
914
+ addresses: {
915
+ 14800: "0x8325C0A0948483EdA023A1A2Fd895e62C5131234",
916
+ 1480: "0x8325C0A0948483EdA023A1A2Fd895e62C5131234"
917
+ }
918
+ },
919
+ DataRegistry: {
920
+ addresses: {
921
+ 14800: "0x8C8788f98385F6ba1adD4234e551ABba0f82Cb7C",
922
+ 1480: "0x8C8788f98385F6ba1adD4234e551ABba0f82Cb7C"
923
+ }
924
+ },
925
+ TeePoolPhala: {
926
+ addresses: {
927
+ 14800: "0xE8EC6BD73b23Ad40E6B9a6f4bD343FAc411bD99A",
928
+ 1480: "0xE8EC6BD73b23Ad40E6B9a6f4bD343FAc411bD99A"
929
+ }
930
+ },
931
+ ComputeEngine: {
932
+ addresses: {
933
+ 14800: "0xb2BFe33FA420c45F1Cf1287542ad81ae935447bd",
934
+ 1480: "0xb2BFe33FA420c45F1Cf1287542ad81ae935447bd"
935
+ }
936
+ },
937
+ // Data Access Infrastructure
938
+ DataRefinerRegistry: {
939
+ addresses: {
940
+ 14800: "0x93c3EF89369fDcf08Be159D9DeF0F18AB6Be008c",
941
+ 1480: "0x93c3EF89369fDcf08Be159D9DeF0F18AB6Be008c"
942
+ }
943
+ },
944
+ QueryEngine: {
945
+ addresses: {
946
+ 14800: "0xd25Eb66EA2452cf3238A2eC6C1FD1B7F5B320490",
947
+ 1480: "0xd25Eb66EA2452cf3238A2eC6C1FD1B7F5B320490"
948
+ }
949
+ },
950
+ VanaTreasury: {
951
+ addresses: {
952
+ 14800: "0x94a1E56e555ac48d092f490fB10CDFaB434915eD",
953
+ 1480: "0x94a1E56e555ac48d092f490fB10CDFaB434915eD"
954
+ }
955
+ },
956
+ ComputeInstructionRegistry: {
957
+ addresses: {
958
+ 14800: "0x5786B12b4c6Ba2bFAF0e77Ed30Bf6d32805563A5",
959
+ 1480: "0x5786B12b4c6Ba2bFAF0e77Ed30Bf6d32805563A5"
960
+ }
961
+ },
962
+ // TEE Pool Variants
963
+ TeePoolEphemeralStandard: {
964
+ addresses: {
965
+ 14800: "0xe124bae846D5ec157f75Bd9e68ca87C4d2AB835A",
966
+ 1480: "0xe124bae846D5ec157f75Bd9e68ca87C4d2AB835A"
967
+ }
968
+ },
969
+ TeePoolPersistentStandard: {
970
+ addresses: {
971
+ 14800: "0xe8bB8d0629651Cf33e0845d743976Dc1f0971d76",
972
+ 1480: "0xe8bB8d0629651Cf33e0845d743976Dc1f0971d76"
973
+ }
974
+ },
975
+ TeePoolPersistentGpu: {
976
+ addresses: {
977
+ 14800: "0x1c346Cd74f8551f8fa13f3F4b6b8dAE22338E6a9",
978
+ 1480: "0x1c346Cd74f8551f8fa13f3F4b6b8dAE22338E6a9"
979
+ }
980
+ },
981
+ TeePoolDedicatedStandard: {
982
+ addresses: {
983
+ 14800: "0xf024b7ac5E8417416f53B41ecfa58C8e9396687d",
984
+ 1480: "0xf024b7ac5E8417416f53B41ecfa58C8e9396687d"
985
+ }
986
+ },
987
+ TeePoolDedicatedGpu: {
988
+ addresses: {
989
+ 14800: "0xB1686FA9620bBf851714d1cB47b8a4Bf4664644E",
990
+ 1480: "0xB1686FA9620bBf851714d1cB47b8a4Bf4664644E"
991
+ }
992
+ },
993
+ // DLP Reward System
994
+ VanaEpoch: {
995
+ addresses: {
996
+ 14800: "0x2063cFF0609D59bCCc196E20Eb58A8696a6b15A0",
997
+ 1480: "0x2063cFF0609D59bCCc196E20Eb58A8696a6b15A0"
998
+ }
999
+ },
1000
+ DLPRegistry: {
1001
+ addresses: {
1002
+ 14800: "0x4D59880a924526d1dD33260552Ff4328b1E18a43",
1003
+ 1480: "0x4D59880a924526d1dD33260552Ff4328b1E18a43"
1004
+ }
1005
+ },
1006
+ DLPRegistryTreasury: {
1007
+ addresses: {
1008
+ 14800: "0xb12ce1d27bEeFe39b6F0110b1AB77C21Aa0c9F9a",
1009
+ 1480: "0xb12ce1d27bEeFe39b6F0110b1AB77C21Aa0c9F9a"
1010
+ }
1011
+ },
1012
+ DLPPerformance: {
1013
+ addresses: {
1014
+ 14800: "0x847715C7DB37cF286611182Be0bD333cbfa29cc1",
1015
+ 1480: "0x847715C7DB37cF286611182Be0bD333cbfa29cc1"
1016
+ }
1017
+ },
1018
+ DLPRewardDeployer: {
1019
+ addresses: {
1020
+ 14800: "0xEFD0F9Ba9De70586b7c4189971cF754adC923B04",
1021
+ 1480: "0xEFD0F9Ba9De70586b7c4189971cF754adC923B04"
1022
+ }
1023
+ },
1024
+ DLPRewardDeployerTreasury: {
1025
+ addresses: {
1026
+ 14800: "0xb547ca8Fe4990fe330FeAeb1C2EBb42F925Af5b8",
1027
+ 1480: "0xb547ca8Fe4990fe330FeAeb1C2EBb42F925Af5b8"
1028
+ }
1029
+ },
1030
+ DLPRewardSwap: {
1031
+ addresses: {
1032
+ 14800: "0x7c6862C46830F0fc3bF3FF509EA1bD0EE7267fB0",
1033
+ 1480: "0x7c6862C46830F0fc3bF3FF509EA1bD0EE7267fB0"
1034
+ }
1035
+ },
1036
+ SwapHelper: {
1037
+ addresses: {
1038
+ 14800: "0x55D5e6F73326315bF2E091e97F04f0770e5C54e2",
1039
+ 1480: "0x55D5e6F73326315bF2E091e97F04f0770e5C54e2"
1040
+ }
1041
+ },
1042
+ // VanaPool (Staking)
1043
+ VanaPoolStaking: {
1044
+ addresses: {
1045
+ 14800: "0x641C18E2F286c86f96CE95C8ec1EB9fC0415Ca0e",
1046
+ 1480: "0x641C18E2F286c86f96CE95C8ec1EB9fC0415Ca0e"
1047
+ }
1048
+ },
1049
+ VanaPoolEntity: {
1050
+ addresses: {
1051
+ 14800: "0x44f20490A82e1f1F1cC25Dd3BA8647034eDdce30",
1052
+ 1480: "0x44f20490A82e1f1F1cC25Dd3BA8647034eDdce30"
1053
+ }
1054
+ },
1055
+ VanaPoolTreasury: {
1056
+ addresses: {
1057
+ 14800: "0x143BE72CF2541604A7691933CAccd6D9cC17c003",
1058
+ 1480: "0x143BE72CF2541604A7691933CAccd6D9cC17c003"
1059
+ }
1060
+ },
1061
+ // DLP Deployment Contracts
1062
+ DAT: {
1063
+ addresses: {
1064
+ 14800: "0xA706b93ccED89f13340673889e29F0a5cd84212d",
1065
+ 1480: "0xA706b93ccED89f13340673889e29F0a5cd84212d"
1066
+ }
1067
+ },
1068
+ DATFactory: {
1069
+ addresses: {
1070
+ 14800: "0x40f8bccF35a75ecef63BC3B1B3E06ffEB9220644",
1071
+ 1480: "0x40f8bccF35a75ecef63BC3B1B3E06ffEB9220644"
1072
+ }
1073
+ },
1074
+ DATPausable: {
1075
+ addresses: {
1076
+ 14800: "0xe69FE86f0B95cC2f8416Fe22815c85DC8887e76e",
1077
+ 1480: "0xe69FE86f0B95cC2f8416Fe22815c85DC8887e76e"
1078
+ }
1079
+ },
1080
+ DATVotes: {
1081
+ addresses: {
1082
+ 14800: "0xaE04c8A77E9B27869eb563720524A9aE0baf1831",
1083
+ 1480: "0xaE04c8A77E9B27869eb563720524A9aE0baf1831"
1084
+ }
1085
+ },
1086
+ // Utility Contracts (no ABIs in SDK)
1087
+ Multicall3: {
1088
+ addresses: {
1089
+ 14800: "0xD8d2dFca27E8797fd779F8547166A2d3B29d360E",
1090
+ 1480: "0xD8d2dFca27E8797fd779F8547166A2d3B29d360E"
1091
+ }
1092
+ },
1093
+ Multisend: {
1094
+ addresses: {
1095
+ 14800: "0x8807e8BCDFbaA8c2761760f3FBA37F6f7F2C5b2d",
1096
+ 1480: "0x8807e8BCDFbaA8c2761760f3FBA37F6f7F2C5b2d"
1097
+ }
1098
+ }
1099
+ };
1100
+ var LEGACY_CONTRACTS = {
1101
+ // DEPRECATED: Original Intel SGX TeePool (PRO-347)
1102
+ TeePool: {
1103
+ addresses: {
1104
+ 14800: "0x3c92fD91639b41f13338CE62f19131e7d19eaa0D",
1105
+ 1480: "0x3c92fD91639b41f13338CE62f19131e7d19eaa0D"
1106
+ }
1107
+ },
1108
+ // DEPRECATED: DLPRoot system (replaced by VanaPool + DLPRewards)
1109
+ DLPRootEpoch: {
1110
+ addresses: {
1111
+ 14800: "0xc3d176cF6BccFCB9225b53B87a95147218e1537F",
1112
+ 1480: "0xc3d176cF6BccFCB9225b53B87a95147218e1537F"
1113
+ }
1114
+ },
1115
+ DLPRootCore: {
1116
+ addresses: {
1117
+ 14800: "0x0aBa5e28228c323A67712101d61a54d4ff5720FD",
1118
+ 1480: "0x0aBa5e28228c323A67712101d61a54d4ff5720FD"
1119
+ }
1120
+ },
1121
+ DLPRoot: {
1122
+ addresses: {
1123
+ 14800: "0xff14346dF2B8Fd0c95BF34f1c92e49417b508AD5",
1124
+ 1480: "0xff14346dF2B8Fd0c95BF34f1c92e49417b508AD5"
1125
+ }
1126
+ },
1127
+ DLPRootMetrics: {
1128
+ addresses: {
1129
+ 14800: "0xbb532917B6407c060Afd9Cb7d53527eCb91d6662",
1130
+ 1480: "0xbb532917B6407c060Afd9Cb7d53527eCb91d6662"
1131
+ }
1132
+ },
1133
+ DLPRootStakesTreasury: {
1134
+ addresses: {
1135
+ 14800: "0x52c3260ED5C235fcA43524CF508e29c897318775",
1136
+ 1480: "0x52c3260ED5C235fcA43524CF508e29c897318775"
1137
+ }
1138
+ },
1139
+ DLPRootRewardsTreasury: {
1140
+ addresses: {
1141
+ 14800: "0xDBFb6B8b9E2eCAEbdE64d665cD553dB81e524479",
1142
+ 1480: "0xDBFb6B8b9E2eCAEbdE64d665cD553dB81e524479"
1143
+ }
1144
+ }
1145
+ };
1146
+ var CONTRACT_ADDRESSES = {
1147
+ 14800: Object.fromEntries(
1148
+ Object.entries(CONTRACTS).map(([name, info]) => [name, info.addresses[14800]]).filter(([, addr]) => addr)
1149
+ ),
1150
+ 1480: Object.fromEntries(
1151
+ Object.entries(CONTRACTS).map(([name, info]) => [name, info.addresses[1480]]).filter(([, addr]) => addr)
1152
+ )
1153
+ };
1154
+ var UTILITY_ADDRESSES = {
1155
+ 14800: {
1156
+ Multicall3: CONTRACTS.Multicall3.addresses[14800],
1157
+ Multisend: CONTRACTS.Multisend.addresses[14800]
1158
+ },
1159
+ 1480: {
1160
+ Multicall3: CONTRACTS.Multicall3.addresses[1480],
1161
+ Multisend: CONTRACTS.Multisend.addresses[1480]
1162
+ }
1163
+ };
1164
+ var LEGACY_ADDRESSES = {
1165
+ 14800: Object.fromEntries(
1166
+ Object.entries(LEGACY_CONTRACTS).map(([name, info]) => [name, info.addresses[14800]]).filter(([, addr]) => addr)
1167
+ ),
1168
+ 1480: Object.fromEntries(
1169
+ Object.entries(LEGACY_CONTRACTS).map(([name, info]) => [name, info.addresses[1480]]).filter(([, addr]) => addr)
1170
+ )
1171
+ };
1172
+ var getContractAddress = (chainId, contract) => {
1173
+ const contractAddress = CONTRACT_ADDRESSES[chainId]?.[contract];
1174
+ if (!contractAddress) {
1175
+ throw new Error(
1176
+ `Contract address not found for ${contract} on chain ${chainId}`
1177
+ );
1178
+ }
1179
+ return contractAddress;
1180
+ };
1181
+ var getUtilityAddress = (chainId, contract) => {
1182
+ return UTILITY_ADDRESSES[chainId][contract];
1183
+ };
1184
+
1185
+ // src/utils/multicall.ts
1186
+ var DEFAULT_OPTIONS = {
1187
+ maxGasPerBatch: 10000000n,
1188
+ // 10M gas - conservative default
1189
+ maxCalldataBytes: 1e5,
1190
+ // 100KB - works with most RPC providers
1191
+ checkpointFrequency: {
1192
+ calls: 32,
1193
+ bytes: 8192
1194
+ // 8KB
1195
+ },
1196
+ allowFailure: false
1197
+ };
1198
+ async function gasAwareMulticall(client, parameters, options = {}) {
1199
+ const chainId = await client.getChainId();
1200
+ const multicall3Address = options.multicallAddress || getUtilityAddress(chainId, "Multicall3");
1201
+ const opts = {
1202
+ ...DEFAULT_OPTIONS,
1203
+ ...options,
1204
+ multicallAddress: multicall3Address,
1205
+ checkpointFrequency: {
1206
+ ...DEFAULT_OPTIONS.checkpointFrequency,
1207
+ ...options.checkpointFrequency
1208
+ }
1209
+ };
1210
+ if (parameters.allowFailure !== void 0) {
1211
+ opts.allowFailure = parameters.allowFailure;
1212
+ }
1213
+ const { contracts } = parameters;
1214
+ if (!contracts || contracts.length === 0) {
1215
+ return [];
1216
+ }
1217
+ const batches = await createBatches(
1218
+ client,
1219
+ contracts,
1220
+ opts
1221
+ );
1222
+ const batchResults = await Promise.all(
1223
+ batches.map((batch, index) => {
1224
+ if (opts.onProgress && index > 0) {
1225
+ const completed = batches.slice(0, index).reduce((sum, b) => sum + b.length, 0);
1226
+ opts.onProgress(completed, contracts.length);
1227
+ }
1228
+ return client.multicall({
1229
+ ...parameters,
1230
+ contracts: batch,
1231
+ multicallAddress: opts.multicallAddress,
1232
+ allowFailure: opts.allowFailure
1233
+ });
1234
+ })
1235
+ );
1236
+ if (opts.onProgress) {
1237
+ opts.onProgress(contracts.length, contracts.length);
1238
+ }
1239
+ return batchResults.flat();
1240
+ }
1241
+ async function createBatches(client, contracts, options) {
1242
+ const batches = [];
1243
+ let currentBatch = [];
1244
+ let currentBytes = 0;
1245
+ let lastCheckpointIndex = 0;
1246
+ let lastCheckpointBytes = 0;
1247
+ let lastEstimatedGas = 0n;
1248
+ for (let i = 0; i < contracts.length; i++) {
1249
+ const contract = contracts[i];
1250
+ const encoded = encodeContractCall(contract);
1251
+ const callBytes = size(encoded);
1252
+ const callsSinceCheckpoint = i - lastCheckpointIndex;
1253
+ const bytesSinceCheckpoint = currentBytes - lastCheckpointBytes;
1254
+ const needsCheckpoint = callsSinceCheckpoint >= options.checkpointFrequency.calls || bytesSinceCheckpoint >= options.checkpointFrequency.bytes;
1255
+ if (needsCheckpoint && currentBatch.length > 0) {
1256
+ try {
1257
+ lastEstimatedGas = await estimateBatchGas(
1258
+ client,
1259
+ currentBatch,
1260
+ options.multicallAddress
1261
+ );
1262
+ lastCheckpointIndex = i;
1263
+ lastCheckpointBytes = currentBytes;
1264
+ } catch (error) {
1265
+ if (currentBatch.length > 1) {
1266
+ const halfBatch = currentBatch.slice(
1267
+ 0,
1268
+ Math.floor(currentBatch.length / 2)
1269
+ );
1270
+ batches.push(halfBatch);
1271
+ currentBatch = currentBatch.slice(halfBatch.length);
1272
+ currentBytes = calculateBatchSize(currentBatch);
1273
+ lastCheckpointIndex = i;
1274
+ lastCheckpointBytes = currentBytes;
1275
+ lastEstimatedGas = 0n;
1276
+ } else {
1277
+ if (!options.allowFailure) {
1278
+ throw new Error(`Gas estimation failed for call ${i}: ${error}`);
1279
+ }
1280
+ currentBatch = [];
1281
+ currentBytes = 0;
1282
+ continue;
1283
+ }
1284
+ }
1285
+ }
1286
+ const wouldExceedCalldata = currentBytes + callBytes > options.maxCalldataBytes;
1287
+ const wouldExceedGas = lastEstimatedGas > 0n && estimateNextGas(lastEstimatedGas, callsSinceCheckpoint + 1) > options.maxGasPerBatch;
1288
+ if ((wouldExceedCalldata || wouldExceedGas) && currentBatch.length > 0) {
1289
+ batches.push(currentBatch);
1290
+ currentBatch = [];
1291
+ currentBytes = 0;
1292
+ lastCheckpointIndex = i;
1293
+ lastCheckpointBytes = 0;
1294
+ lastEstimatedGas = 0n;
1295
+ }
1296
+ currentBatch.push(contract);
1297
+ currentBytes += callBytes;
1298
+ }
1299
+ if (currentBatch.length > 0) {
1300
+ batches.push(currentBatch);
1301
+ }
1302
+ return batches;
1303
+ }
1304
+ function encodeContractCall(contract) {
1305
+ const { abi, functionName, args } = contract;
1306
+ return encodeFunctionData({
1307
+ abi,
1308
+ functionName,
1309
+ args
1310
+ });
1311
+ }
1312
+ function calculateBatchSize(batch) {
1313
+ return batch.reduce((total, contract) => {
1314
+ const encoded = encodeContractCall(contract);
1315
+ return total + size(encoded);
1316
+ }, 0);
1317
+ }
1318
+ async function estimateBatchGas(client, batch, multicallAddress) {
1319
+ const calls = batch.map((contract) => ({
1320
+ target: contract.address,
1321
+ allowFailure: false,
1322
+ callData: encodeContractCall(contract)
1323
+ }));
1324
+ const gas = await client.estimateGas({
1325
+ to: multicallAddress,
1326
+ data: encodeFunctionData({
1327
+ abi: multicall3Abi,
1328
+ functionName: "aggregate3",
1329
+ args: [calls]
1330
+ })
1331
+ });
1332
+ return gas;
1333
+ }
1334
+ function estimateNextGas(lastGas, callsSinceCheckpoint) {
1335
+ if (callsSinceCheckpoint === 0) return lastGas;
1336
+ const avgGasPerCall = lastGas / BigInt(Math.max(1, callsSinceCheckpoint - 1));
1337
+ const estimatedGas = lastGas + avgGasPerCall;
1338
+ return estimatedGas * 110n / 100n;
1339
+ }
1340
+ var multicall3Abi = [
1341
+ {
1342
+ name: "aggregate3",
1343
+ type: "function",
1344
+ stateMutability: "payable",
1345
+ inputs: [
1346
+ {
1347
+ name: "calls",
1348
+ type: "tuple[]",
1349
+ components: [
1350
+ { name: "target", type: "address" },
1351
+ { name: "allowFailure", type: "bool" },
1352
+ { name: "callData", type: "bytes" }
1353
+ ]
1354
+ }
1355
+ ],
1356
+ outputs: [
1357
+ {
1358
+ name: "returnData",
1359
+ type: "tuple[]",
1360
+ components: [
1361
+ { name: "success", type: "bool" },
1362
+ { name: "returnData", type: "bytes" }
1363
+ ]
1364
+ }
1365
+ ]
1366
+ }
1367
+ ];
1368
+
872
1369
  // src/utils/transactionParsing.ts
873
1370
  import { parseEventLogs } from "viem";
874
1371
 
875
1372
  // src/config/eventMappings.ts
876
1373
  var EVENT_MAPPINGS = {
877
- // Permission operations
1374
+ // DataPortabilityPermissions operations
878
1375
  grant: {
879
1376
  contract: "DataPortabilityPermissions",
880
1377
  event: "PermissionAdded"
@@ -883,6 +1380,15 @@ var EVENT_MAPPINGS = {
883
1380
  contract: "DataPortabilityPermissions",
884
1381
  event: "PermissionRevoked"
885
1382
  },
1383
+ revokePermission: {
1384
+ contract: "DataPortabilityPermissions",
1385
+ event: "PermissionRevoked"
1386
+ },
1387
+ addServerFilesAndPermissions: {
1388
+ contract: "DataPortabilityPermissions",
1389
+ event: "PermissionAdded"
1390
+ },
1391
+ // DataPortabilityServers operations
886
1392
  trustServer: {
887
1393
  contract: "DataPortabilityServers",
888
1394
  event: "ServerTrusted"
@@ -891,15 +1397,51 @@ var EVENT_MAPPINGS = {
891
1397
  contract: "DataPortabilityServers",
892
1398
  event: "ServerUntrusted"
893
1399
  },
894
- // Data registry operations
1400
+ registerServer: {
1401
+ contract: "DataPortabilityServers",
1402
+ event: "ServerRegistered"
1403
+ },
1404
+ updateServer: {
1405
+ contract: "DataPortabilityServers",
1406
+ event: "ServerUpdated"
1407
+ },
1408
+ addAndTrustServer: {
1409
+ contract: "DataPortabilityServers",
1410
+ event: "ServerTrusted"
1411
+ },
1412
+ // DataRegistry operations
895
1413
  addFile: {
896
1414
  contract: "DataRegistry",
897
1415
  event: "FileAdded"
898
1416
  },
1417
+ addFileWithPermissionsAndSchema: {
1418
+ contract: "DataRegistry",
1419
+ event: "FileAdded"
1420
+ },
1421
+ addFileWithSchema: {
1422
+ contract: "DataRegistry",
1423
+ event: "FileAdded"
1424
+ },
1425
+ addFileWithPermissions: {
1426
+ contract: "DataRegistry",
1427
+ event: "FileAdded"
1428
+ },
899
1429
  addRefinement: {
900
1430
  contract: "DataRegistry",
901
1431
  event: "RefinementAdded"
902
1432
  },
1433
+ addRefiner: {
1434
+ contract: "DataRefinerRegistry",
1435
+ event: "RefinerAdded"
1436
+ },
1437
+ updateSchemaId: {
1438
+ contract: "DataRefinerRegistry",
1439
+ event: "SchemaAdded"
1440
+ },
1441
+ addSchema: {
1442
+ contract: "DataRefinerRegistry",
1443
+ event: "SchemaAdded"
1444
+ },
903
1445
  updateRefinement: {
904
1446
  contract: "DataRegistry",
905
1447
  event: "RefinementUpdated"
@@ -907,10 +1449,15 @@ var EVENT_MAPPINGS = {
907
1449
  addFilePermission: {
908
1450
  contract: "DataRegistry",
909
1451
  event: "PermissionGranted"
1452
+ },
1453
+ // DataPortabilityGrantees operations
1454
+ registerGrantee: {
1455
+ contract: "DataPortabilityGrantees",
1456
+ event: "GranteeRegistered"
910
1457
  }
911
1458
  };
912
1459
 
913
- // src/abi/ComputeEngineImplementation.ts
1460
+ // src/generated/abi/ComputeEngineImplementation.ts
914
1461
  var ComputeEngineABI = [
915
1462
  {
916
1463
  inputs: [],
@@ -2195,7 +2742,7 @@ var ComputeEngineABI = [
2195
2742
  }
2196
2743
  ];
2197
2744
 
2198
- // src/abi/DataRegistryImplementation.ts
2745
+ // src/generated/abi/DataRegistryImplementation.ts
2199
2746
  var DataRegistryABI = [
2200
2747
  {
2201
2748
  inputs: [],
@@ -3385,7 +3932,7 @@ var DataRegistryABI = [
3385
3932
  }
3386
3933
  ];
3387
3934
 
3388
- // src/abi/TeePoolImplementation.ts
3935
+ // src/generated/abi/TeePoolImplementation.ts
3389
3936
  var TeePoolABI = [
3390
3937
  {
3391
3938
  inputs: [],
@@ -4670,7 +5217,7 @@ var TeePoolABI = [
4670
5217
  }
4671
5218
  ];
4672
5219
 
4673
- // src/abi/TeePoolPhalaImplementation.ts
5220
+ // src/generated/abi/TeePoolPhalaImplementation.ts
4674
5221
  var TeePoolPhalaABI = [
4675
5222
  {
4676
5223
  inputs: [],
@@ -5955,7 +6502,7 @@ var TeePoolPhalaABI = [
5955
6502
  }
5956
6503
  ];
5957
6504
 
5958
- // src/abi/DataPortabilityPermissionsImplementation.ts
6505
+ // src/generated/abi/DataPortabilityPermissionsImplementation.ts
5959
6506
  var DataPortabilityPermissionsABI = [
5960
6507
  {
5961
6508
  inputs: [],
@@ -7223,7 +7770,7 @@ var DataPortabilityPermissionsABI = [
7223
7770
  }
7224
7771
  ];
7225
7772
 
7226
- // src/abi/DataPortabilityServersImplementation.ts
7773
+ // src/generated/abi/DataPortabilityServersImplementation.ts
7227
7774
  var DataPortabilityServersABI = [
7228
7775
  {
7229
7776
  inputs: [],
@@ -8615,7 +9162,7 @@ var DataPortabilityServersABI = [
8615
9162
  }
8616
9163
  ];
8617
9164
 
8618
- // src/abi/DataPortabilityGranteesImplementation.ts
9165
+ // src/generated/abi/DataPortabilityGranteesImplementation.ts
8619
9166
  var DataPortabilityGranteesABI = [
8620
9167
  {
8621
9168
  inputs: [],
@@ -9475,7 +10022,7 @@ var DataPortabilityGranteesABI = [
9475
10022
  }
9476
10023
  ];
9477
10024
 
9478
- // src/abi/DataRefinerRegistryImplementation.ts
10025
+ // src/generated/abi/DataRefinerRegistryImplementation.ts
9479
10026
  var DataRefinerRegistryABI = [
9480
10027
  {
9481
10028
  inputs: [],
@@ -10431,7 +10978,7 @@ var DataRefinerRegistryABI = [
10431
10978
  }
10432
10979
  ];
10433
10980
 
10434
- // src/abi/QueryEngineImplementation.ts
10981
+ // src/generated/abi/QueryEngineImplementation.ts
10435
10982
  var QueryEngineABI = [
10436
10983
  {
10437
10984
  inputs: [],
@@ -11722,7 +12269,7 @@ var QueryEngineABI = [
11722
12269
  }
11723
12270
  ];
11724
12271
 
11725
- // src/abi/ComputeInstructionRegistryImplementation.ts
12272
+ // src/generated/abi/ComputeInstructionRegistryImplementation.ts
11726
12273
  var ComputeInstructionRegistryABI = [
11727
12274
  {
11728
12275
  inputs: [],
@@ -12428,7 +12975,7 @@ var ComputeInstructionRegistryABI = [
12428
12975
  }
12429
12976
  ];
12430
12977
 
12431
- // src/abi/TeePoolEphemeralStandardImplementation.ts
12978
+ // src/generated/abi/TeePoolEphemeralStandardImplementation.ts
12432
12979
  var TeePoolEphemeralStandardABI = [
12433
12980
  {
12434
12981
  inputs: [],
@@ -13336,7 +13883,7 @@ var TeePoolEphemeralStandardABI = [
13336
13883
  }
13337
13884
  ];
13338
13885
 
13339
- // src/abi/TeePoolPersistentStandardImplementation.ts
13886
+ // src/generated/abi/TeePoolPersistentStandardImplementation.ts
13340
13887
  var TeePoolPersistentStandardABI = [
13341
13888
  {
13342
13889
  inputs: [],
@@ -14244,7 +14791,7 @@ var TeePoolPersistentStandardABI = [
14244
14791
  }
14245
14792
  ];
14246
14793
 
14247
- // src/abi/TeePoolPersistentGpuImplementation.ts
14794
+ // src/generated/abi/TeePoolPersistentGpuImplementation.ts
14248
14795
  var TeePoolPersistentGpuABI = [
14249
14796
  {
14250
14797
  inputs: [],
@@ -15152,7 +15699,7 @@ var TeePoolPersistentGpuABI = [
15152
15699
  }
15153
15700
  ];
15154
15701
 
15155
- // src/abi/TeePoolDedicatedStandardImplementation.ts
15702
+ // src/generated/abi/TeePoolDedicatedStandardImplementation.ts
15156
15703
  var TeePoolDedicatedStandardABI = [
15157
15704
  {
15158
15705
  inputs: [],
@@ -16060,7 +16607,7 @@ var TeePoolDedicatedStandardABI = [
16060
16607
  }
16061
16608
  ];
16062
16609
 
16063
- // src/abi/TeePoolDedicatedGpuImplementation.ts
16610
+ // src/generated/abi/TeePoolDedicatedGpuImplementation.ts
16064
16611
  var TeePoolDedicatedGpuABI = [
16065
16612
  {
16066
16613
  inputs: [],
@@ -16968,7 +17515,7 @@ var TeePoolDedicatedGpuABI = [
16968
17515
  }
16969
17516
  ];
16970
17517
 
16971
- // src/abi/VanaEpochImplementation.ts
17518
+ // src/generated/abi/VanaEpochImplementation.ts
16972
17519
  var VanaEpochABI = [
16973
17520
  {
16974
17521
  inputs: [],
@@ -18128,7 +18675,7 @@ var VanaEpochABI = [
18128
18675
  }
18129
18676
  ];
18130
18677
 
18131
- // src/abi/DLPRegistryImplementation.ts
18678
+ // src/generated/abi/DLPRegistryImplementation.ts
18132
18679
  var DLPRegistryABI = [
18133
18680
  {
18134
18681
  inputs: [],
@@ -19569,7 +20116,7 @@ var DLPRegistryABI = [
19569
20116
  }
19570
20117
  ];
19571
20118
 
19572
- // src/abi/DLPTreasuryImplementation.ts
20119
+ // src/generated/abi/DLPTreasuryImplementation.ts
19573
20120
  var DLPRegistryTreasuryABI = [
19574
20121
  {
19575
20122
  inputs: [],
@@ -20153,7 +20700,7 @@ var DLPRegistryTreasuryABI = [
20153
20700
  }
20154
20701
  ];
20155
20702
 
20156
- // src/abi/DLPRewardDeployerTreasuryImplementation.ts
20703
+ // src/generated/abi/DLPRewardDeployerTreasuryImplementation.ts
20157
20704
  var DLPRewardDeployerTreasuryABI = [
20158
20705
  {
20159
20706
  inputs: [],
@@ -20737,7 +21284,7 @@ var DLPRewardDeployerTreasuryABI = [
20737
21284
  }
20738
21285
  ];
20739
21286
 
20740
- // src/abi/DLPPerformanceImplementation.ts
21287
+ // src/generated/abi/DLPPerformanceImplementation.ts
20741
21288
  var DLPPerformanceABI = [
20742
21289
  {
20743
21290
  inputs: [],
@@ -21869,7 +22416,7 @@ var DLPPerformanceABI = [
21869
22416
  }
21870
22417
  ];
21871
22418
 
21872
- // src/abi/DLPRewardDeployerImplementation.ts
22419
+ // src/generated/abi/DLPRewardDeployerImplementation.ts
21873
22420
  var DLPRewardDeployerABI = [
21874
22421
  {
21875
22422
  inputs: [],
@@ -22789,7 +23336,7 @@ var DLPRewardDeployerABI = [
22789
23336
  }
22790
23337
  ];
22791
23338
 
22792
- // src/abi/DLPRewardSwapImplementation.ts
23339
+ // src/generated/abi/DLPRewardSwapImplementation.ts
22793
23340
  var DLPRewardSwapABI = [
22794
23341
  {
22795
23342
  inputs: [],
@@ -23700,7 +24247,7 @@ var DLPRewardSwapABI = [
23700
24247
  }
23701
24248
  ];
23702
24249
 
23703
- // src/abi/SwapHelperImplementation.ts
24250
+ // src/generated/abi/SwapHelperImplementation.ts
23704
24251
  var SwapHelperABI = [
23705
24252
  {
23706
24253
  inputs: [],
@@ -24691,7 +25238,7 @@ var SwapHelperABI = [
24691
25238
  }
24692
25239
  ];
24693
25240
 
24694
- // src/abi/DLPRootImplementation.ts
25241
+ // src/generated/abi/DLPRootImplementation.ts
24695
25242
  var DLPRootImplementation2Abi = [
24696
25243
  {
24697
25244
  inputs: [],
@@ -26309,7 +26856,7 @@ var DLPRootImplementation2Abi = [
26309
26856
  }
26310
26857
  ];
26311
26858
 
26312
- // src/abi/DataLiquidityPoolImplementation.ts
26859
+ // src/generated/abi/DataLiquidityPoolImplementation.ts
26313
26860
  var DataLiquidityPoolImplementationAbi = [
26314
26861
  {
26315
26862
  inputs: [],
@@ -27268,7 +27815,7 @@ var DataLiquidityPoolImplementationAbi = [
27268
27815
  }
27269
27816
  ];
27270
27817
 
27271
- // src/abi/DLPRegistryTreasuryImplementation.ts
27818
+ // src/generated/abi/DLPRegistryTreasuryImplementation.ts
27272
27819
  var DLPRegistryTreasuryABI2 = [
27273
27820
  {
27274
27821
  inputs: [],
@@ -27852,7 +28399,7 @@ var DLPRegistryTreasuryABI2 = [
27852
28399
  }
27853
28400
  ];
27854
28401
 
27855
- // src/abi/VanaPoolStakingImplementation.ts
28402
+ // src/generated/abi/VanaPoolStakingImplementation.ts
27856
28403
  var VanaPoolStakingABI = [
27857
28404
  {
27858
28405
  inputs: [],
@@ -28745,7 +29292,7 @@ var VanaPoolStakingABI = [
28745
29292
  }
28746
29293
  ];
28747
29294
 
28748
- // src/abi/VanaPoolEntityImplementation.ts
29295
+ // src/generated/abi/VanaPoolEntityImplementation.ts
28749
29296
  var VanaPoolEntityABI = [
28750
29297
  {
28751
29298
  inputs: [],
@@ -29951,7 +30498,7 @@ var VanaPoolEntityABI = [
29951
30498
  }
29952
30499
  ];
29953
30500
 
29954
- // src/abi/VanaPoolTreasuryImplementation.ts
30501
+ // src/generated/abi/VanaPoolTreasuryImplementation.ts
29955
30502
  var VanaPoolTreasuryABI = [
29956
30503
  {
29957
30504
  inputs: [],
@@ -30461,7 +31008,7 @@ var VanaPoolTreasuryABI = [
30461
31008
  }
30462
31009
  ];
30463
31010
 
30464
- // src/abi/DATImplementation.ts
31011
+ // src/generated/abi/DATImplementation.ts
30465
31012
  var DATABI = [
30466
31013
  {
30467
31014
  inputs: [],
@@ -31367,7 +31914,7 @@ var DATABI = [
31367
31914
  }
31368
31915
  ];
31369
31916
 
31370
- // src/abi/DATFactoryImplementation.ts
31917
+ // src/generated/abi/DATFactoryImplementation.ts
31371
31918
  var DATFactoryABI = [
31372
31919
  {
31373
31920
  inputs: [],
@@ -32221,7 +32768,7 @@ var DATFactoryABI = [
32221
32768
  }
32222
32769
  ];
32223
32770
 
32224
- // src/abi/DATPausableImplementation.ts
32771
+ // src/generated/abi/DATPausableImplementation.ts
32225
32772
  var DATPausableABI = [
32226
32773
  {
32227
32774
  inputs: [],
@@ -33716,7 +34263,7 @@ var DATPausableABI = [
33716
34263
  }
33717
34264
  ];
33718
34265
 
33719
- // src/abi/DATVotesImplementation.ts
34266
+ // src/generated/abi/DATVotesImplementation.ts
33720
34267
  var DATVotesABI = [
33721
34268
  {
33722
34269
  inputs: [],
@@ -35148,7 +35695,7 @@ var DATVotesABI = [
35148
35695
  }
35149
35696
  ];
35150
35697
 
35151
- // src/abi/index.ts
35698
+ // src/generated/abi/index.ts
35152
35699
  var contractAbis = {
35153
35700
  DataPortabilityPermissions: DataPortabilityPermissionsABI,
35154
35701
  DataPortabilityServers: DataPortabilityServersABI,
@@ -35254,288 +35801,99 @@ async function parseTransactionResult(context, hash, operation) {
35254
35801
  }
35255
35802
  }
35256
35803
 
35257
- // src/config/addresses.ts
35258
- var CONTRACTS = {
35259
- // Data Portability Contracts (New Architecture)
35260
- DataPortabilityPermissions: {
35261
- addresses: {
35262
- 14800: "0xD54523048AdD05b4d734aFaE7C68324Ebb7373eF",
35263
- 1480: "0xD54523048AdD05b4d734aFaE7C68324Ebb7373eF"
35264
- }
35265
- },
35266
- DataPortabilityServers: {
35267
- addresses: {
35268
- 14800: "0x1483B1F634DBA75AeaE60da7f01A679aabd5ee2c",
35269
- 1480: "0x1483B1F634DBA75AeaE60da7f01A679aabd5ee2c"
35270
- }
35271
- },
35272
- DataPortabilityGrantees: {
35273
- addresses: {
35274
- 14800: "0x8325C0A0948483EdA023A1A2Fd895e62C5131234",
35275
- 1480: "0x8325C0A0948483EdA023A1A2Fd895e62C5131234"
35276
- }
35277
- },
35278
- DataRegistry: {
35279
- addresses: {
35280
- 14800: "0x8C8788f98385F6ba1adD4234e551ABba0f82Cb7C",
35281
- 1480: "0x8C8788f98385F6ba1adD4234e551ABba0f82Cb7C"
35282
- }
35283
- },
35284
- TeePoolPhala: {
35285
- addresses: {
35286
- 14800: "0xE8EC6BD73b23Ad40E6B9a6f4bD343FAc411bD99A",
35287
- 1480: "0xE8EC6BD73b23Ad40E6B9a6f4bD343FAc411bD99A"
35288
- }
35289
- },
35290
- ComputeEngine: {
35291
- addresses: {
35292
- 14800: "0xb2BFe33FA420c45F1Cf1287542ad81ae935447bd",
35293
- 1480: "0xb2BFe33FA420c45F1Cf1287542ad81ae935447bd"
35294
- }
35295
- },
35296
- // Data Access Infrastructure
35297
- DataRefinerRegistry: {
35298
- addresses: {
35299
- 14800: "0x93c3EF89369fDcf08Be159D9DeF0F18AB6Be008c",
35300
- 1480: "0x93c3EF89369fDcf08Be159D9DeF0F18AB6Be008c"
35301
- }
35302
- },
35303
- QueryEngine: {
35304
- addresses: {
35305
- 14800: "0xd25Eb66EA2452cf3238A2eC6C1FD1B7F5B320490",
35306
- 1480: "0xd25Eb66EA2452cf3238A2eC6C1FD1B7F5B320490"
35307
- }
35308
- },
35309
- VanaTreasury: {
35310
- addresses: {
35311
- 14800: "0x94a1E56e555ac48d092f490fB10CDFaB434915eD",
35312
- 1480: "0x94a1E56e555ac48d092f490fB10CDFaB434915eD"
35313
- }
35314
- },
35315
- ComputeInstructionRegistry: {
35316
- addresses: {
35317
- 14800: "0x5786B12b4c6Ba2bFAF0e77Ed30Bf6d32805563A5",
35318
- 1480: "0x5786B12b4c6Ba2bFAF0e77Ed30Bf6d32805563A5"
35319
- }
35320
- },
35321
- // TEE Pool Variants
35322
- TeePoolEphemeralStandard: {
35323
- addresses: {
35324
- 14800: "0xe124bae846D5ec157f75Bd9e68ca87C4d2AB835A",
35325
- 1480: "0xe124bae846D5ec157f75Bd9e68ca87C4d2AB835A"
35326
- }
35327
- },
35328
- TeePoolPersistentStandard: {
35329
- addresses: {
35330
- 14800: "0xe8bB8d0629651Cf33e0845d743976Dc1f0971d76",
35331
- 1480: "0xe8bB8d0629651Cf33e0845d743976Dc1f0971d76"
35332
- }
35333
- },
35334
- TeePoolPersistentGpu: {
35335
- addresses: {
35336
- 14800: "0x1c346Cd74f8551f8fa13f3F4b6b8dAE22338E6a9",
35337
- 1480: "0x1c346Cd74f8551f8fa13f3F4b6b8dAE22338E6a9"
35338
- }
35339
- },
35340
- TeePoolDedicatedStandard: {
35341
- addresses: {
35342
- 14800: "0xf024b7ac5E8417416f53B41ecfa58C8e9396687d",
35343
- 1480: "0xf024b7ac5E8417416f53B41ecfa58C8e9396687d"
35344
- }
35345
- },
35346
- TeePoolDedicatedGpu: {
35347
- addresses: {
35348
- 14800: "0xB1686FA9620bBf851714d1cB47b8a4Bf4664644E",
35349
- 1480: "0xB1686FA9620bBf851714d1cB47b8a4Bf4664644E"
35350
- }
35351
- },
35352
- // DLP Reward System
35353
- VanaEpoch: {
35354
- addresses: {
35355
- 14800: "0x2063cFF0609D59bCCc196E20Eb58A8696a6b15A0",
35356
- 1480: "0x2063cFF0609D59bCCc196E20Eb58A8696a6b15A0"
35357
- }
35358
- },
35359
- DLPRegistry: {
35360
- addresses: {
35361
- 14800: "0x4D59880a924526d1dD33260552Ff4328b1E18a43",
35362
- 1480: "0x4D59880a924526d1dD33260552Ff4328b1E18a43"
35363
- }
35364
- },
35365
- DLPRegistryTreasury: {
35366
- addresses: {
35367
- 14800: "0xb12ce1d27bEeFe39b6F0110b1AB77C21Aa0c9F9a",
35368
- 1480: "0xb12ce1d27bEeFe39b6F0110b1AB77C21Aa0c9F9a"
35369
- }
35370
- },
35371
- DLPPerformance: {
35372
- addresses: {
35373
- 14800: "0x847715C7DB37cF286611182Be0bD333cbfa29cc1",
35374
- 1480: "0x847715C7DB37cF286611182Be0bD333cbfa29cc1"
35375
- }
35376
- },
35377
- DLPRewardDeployer: {
35378
- addresses: {
35379
- 14800: "0xEFD0F9Ba9De70586b7c4189971cF754adC923B04",
35380
- 1480: "0xEFD0F9Ba9De70586b7c4189971cF754adC923B04"
35381
- }
35382
- },
35383
- DLPRewardDeployerTreasury: {
35384
- addresses: {
35385
- 14800: "0xb547ca8Fe4990fe330FeAeb1C2EBb42F925Af5b8",
35386
- 1480: "0xb547ca8Fe4990fe330FeAeb1C2EBb42F925Af5b8"
35387
- }
35388
- },
35389
- DLPRewardSwap: {
35390
- addresses: {
35391
- 14800: "0x7c6862C46830F0fc3bF3FF509EA1bD0EE7267fB0",
35392
- 1480: "0x7c6862C46830F0fc3bF3FF509EA1bD0EE7267fB0"
35393
- }
35394
- },
35395
- SwapHelper: {
35396
- addresses: {
35397
- 14800: "0x55D5e6F73326315bF2E091e97F04f0770e5C54e2",
35398
- 1480: "0x55D5e6F73326315bF2E091e97F04f0770e5C54e2"
35399
- }
35400
- },
35401
- // VanaPool (Staking)
35402
- VanaPoolStaking: {
35403
- addresses: {
35404
- 14800: "0x641C18E2F286c86f96CE95C8ec1EB9fC0415Ca0e",
35405
- 1480: "0x641C18E2F286c86f96CE95C8ec1EB9fC0415Ca0e"
35406
- }
35407
- },
35408
- VanaPoolEntity: {
35409
- addresses: {
35410
- 14800: "0x44f20490A82e1f1F1cC25Dd3BA8647034eDdce30",
35411
- 1480: "0x44f20490A82e1f1F1cC25Dd3BA8647034eDdce30"
35412
- }
35413
- },
35414
- VanaPoolTreasury: {
35415
- addresses: {
35416
- 14800: "0x143BE72CF2541604A7691933CAccd6D9cC17c003",
35417
- 1480: "0x143BE72CF2541604A7691933CAccd6D9cC17c003"
35418
- }
35419
- },
35420
- // DLP Deployment Contracts
35421
- DAT: {
35422
- addresses: {
35423
- 14800: "0xA706b93ccED89f13340673889e29F0a5cd84212d",
35424
- 1480: "0xA706b93ccED89f13340673889e29F0a5cd84212d"
35425
- }
35426
- },
35427
- DATFactory: {
35428
- addresses: {
35429
- 14800: "0x40f8bccF35a75ecef63BC3B1B3E06ffEB9220644",
35430
- 1480: "0x40f8bccF35a75ecef63BC3B1B3E06ffEB9220644"
35431
- }
35432
- },
35433
- DATPausable: {
35434
- addresses: {
35435
- 14800: "0xe69FE86f0B95cC2f8416Fe22815c85DC8887e76e",
35436
- 1480: "0xe69FE86f0B95cC2f8416Fe22815c85DC8887e76e"
35437
- }
35438
- },
35439
- DATVotes: {
35440
- addresses: {
35441
- 14800: "0xaE04c8A77E9B27869eb563720524A9aE0baf1831",
35442
- 1480: "0xaE04c8A77E9B27869eb563720524A9aE0baf1831"
35443
- }
35444
- },
35445
- // Utility Contracts (no ABIs in SDK)
35446
- Multicall3: {
35447
- addresses: {
35448
- 14800: "0xD8d2dFca27E8797fd779F8547166A2d3B29d360E",
35449
- 1480: "0xD8d2dFca27E8797fd779F8547166A2d3B29d360E"
35450
- }
35451
- },
35452
- Multisend: {
35453
- addresses: {
35454
- 14800: "0x8807e8BCDFbaA8c2761760f3FBA37F6f7F2C5b2d",
35455
- 1480: "0x8807e8BCDFbaA8c2761760f3FBA37F6f7F2C5b2d"
35456
- }
35804
+ // src/utils/transactionHandle.ts
35805
+ var TransactionHandle = class {
35806
+ constructor(context, hash, operation) {
35807
+ this.context = context;
35808
+ this.hash = hash;
35809
+ this.operation = operation;
35810
+ __publicField(this, "_receipt");
35811
+ __publicField(this, "_eventData");
35812
+ __publicField(this, "_receiptPromise");
35813
+ __publicField(this, "_eventPromise");
35457
35814
  }
35458
- };
35459
- var LEGACY_CONTRACTS = {
35460
- // DEPRECATED: Original Intel SGX TeePool (PRO-347)
35461
- TeePool: {
35462
- addresses: {
35463
- 14800: "0x3c92fD91639b41f13338CE62f19131e7d19eaa0D",
35464
- 1480: "0x3c92fD91639b41f13338CE62f19131e7d19eaa0D"
35465
- }
35466
- },
35467
- // DEPRECATED: DLPRoot system (replaced by VanaPool + DLPRewards)
35468
- DLPRootEpoch: {
35469
- addresses: {
35470
- 14800: "0xc3d176cF6BccFCB9225b53B87a95147218e1537F",
35471
- 1480: "0xc3d176cF6BccFCB9225b53B87a95147218e1537F"
35472
- }
35473
- },
35474
- DLPRootCore: {
35475
- addresses: {
35476
- 14800: "0x0aBa5e28228c323A67712101d61a54d4ff5720FD",
35477
- 1480: "0x0aBa5e28228c323A67712101d61a54d4ff5720FD"
35478
- }
35479
- },
35480
- DLPRoot: {
35481
- addresses: {
35482
- 14800: "0xff14346dF2B8Fd0c95BF34f1c92e49417b508AD5",
35483
- 1480: "0xff14346dF2B8Fd0c95BF34f1c92e49417b508AD5"
35484
- }
35485
- },
35486
- DLPRootMetrics: {
35487
- addresses: {
35488
- 14800: "0xbb532917B6407c060Afd9Cb7d53527eCb91d6662",
35489
- 1480: "0xbb532917B6407c060Afd9Cb7d53527eCb91d6662"
35815
+ /**
35816
+ * Waits for transaction confirmation and returns the receipt.
35817
+ * Results are memoized - multiple calls return the same promise.
35818
+ *
35819
+ * @param options Optional timeout configuration
35820
+ * @param options.timeout Timeout in milliseconds (default: 30000)
35821
+ * @returns Transaction receipt with gas usage, logs, and status
35822
+ */
35823
+ async waitForReceipt(options) {
35824
+ if (this._receipt) {
35825
+ return this._receipt;
35826
+ }
35827
+ if (!this._receiptPromise) {
35828
+ this._receiptPromise = this.context.publicClient.waitForTransactionReceipt({
35829
+ hash: this.hash,
35830
+ timeout: options?.timeout ?? 3e4
35831
+ }).then((receipt) => {
35832
+ this._receipt = receipt;
35833
+ return receipt;
35834
+ });
35490
35835
  }
35491
- },
35492
- DLPRootStakesTreasury: {
35493
- addresses: {
35494
- 14800: "0x52c3260ED5C235fcA43524CF508e29c897318775",
35495
- 1480: "0x52c3260ED5C235fcA43524CF508e29c897318775"
35836
+ return this._receiptPromise;
35837
+ }
35838
+ /**
35839
+ * Waits for transaction confirmation and parses emitted events.
35840
+ * Results are memoized - multiple calls return the same promise.
35841
+ *
35842
+ * @returns Parsed event data with transaction metadata
35843
+ * @throws {Error} If no operation was specified for event parsing
35844
+ */
35845
+ async waitForEvents() {
35846
+ if (this._eventData) {
35847
+ return this._eventData;
35496
35848
  }
35497
- },
35498
- DLPRootRewardsTreasury: {
35499
- addresses: {
35500
- 14800: "0xDBFb6B8b9E2eCAEbdE64d665cD553dB81e524479",
35501
- 1480: "0xDBFb6B8b9E2eCAEbdE64d665cD553dB81e524479"
35849
+ if (!this._eventPromise) {
35850
+ if (!this.operation) {
35851
+ throw new Error(
35852
+ "Cannot parse events: no operation specified. Use waitForReceipt() instead or ensure the operation is configured."
35853
+ );
35854
+ }
35855
+ this._eventPromise = parseTransactionResult(
35856
+ this.context,
35857
+ this.hash,
35858
+ this.operation
35859
+ ).then((eventData) => {
35860
+ this._eventData = eventData;
35861
+ return eventData;
35862
+ });
35502
35863
  }
35864
+ return this._eventPromise;
35503
35865
  }
35504
- };
35505
- var CONTRACT_ADDRESSES = {
35506
- 14800: Object.fromEntries(
35507
- Object.entries(CONTRACTS).map(([name, info]) => [name, info.addresses[14800]]).filter(([, addr]) => addr)
35508
- ),
35509
- 1480: Object.fromEntries(
35510
- Object.entries(CONTRACTS).map(([name, info]) => [name, info.addresses[1480]]).filter(([, addr]) => addr)
35511
- )
35512
- };
35513
- var UTILITY_ADDRESSES = {
35514
- 14800: {
35515
- Multicall3: CONTRACTS.Multicall3.addresses[14800],
35516
- Multisend: CONTRACTS.Multisend.addresses[14800]
35517
- },
35518
- 1480: {
35519
- Multicall3: CONTRACTS.Multicall3.addresses[1480],
35520
- Multisend: CONTRACTS.Multisend.addresses[1480]
35866
+ /**
35867
+ * Enables string coercion for backwards compatibility.
35868
+ * Allows TransactionHandle to be used anywhere a Hash is expected.
35869
+ *
35870
+ * @example
35871
+ * ```typescript
35872
+ * const hash: Hash = tx; // Works via toString()
35873
+ * console.log(`Transaction: ${tx}`); // Prints hash
35874
+ * ```
35875
+ * @returns The transaction hash as a string
35876
+ */
35877
+ toString() {
35878
+ return this.hash;
35521
35879
  }
35522
- };
35523
- var LEGACY_ADDRESSES = {
35524
- 14800: Object.fromEntries(
35525
- Object.entries(LEGACY_CONTRACTS).map(([name, info]) => [name, info.addresses[14800]]).filter(([, addr]) => addr)
35526
- ),
35527
- 1480: Object.fromEntries(
35528
- Object.entries(LEGACY_CONTRACTS).map(([name, info]) => [name, info.addresses[1480]]).filter(([, addr]) => addr)
35529
- )
35530
- };
35531
- var getContractAddress = (chainId, contract) => {
35532
- const contractAddress = CONTRACT_ADDRESSES[chainId]?.[contract];
35533
- if (!contractAddress) {
35534
- throw new Error(
35535
- `Contract address not found for ${contract} on chain ${chainId}`
35536
- );
35880
+ /**
35881
+ * JSON serialization support.
35882
+ * Returns the hash when serialized to JSON.
35883
+ *
35884
+ * @returns The transaction hash for JSON serialization
35885
+ */
35886
+ toJSON() {
35887
+ return this.hash;
35888
+ }
35889
+ /**
35890
+ * Custom inspect for Node.js console.log
35891
+ *
35892
+ * @returns Formatted string representation for debugging
35893
+ */
35894
+ [Symbol.for("nodejs.util.inspect.custom")]() {
35895
+ return `TransactionHandle { hash: '${this.hash}', operation: '${this.operation ?? "none"}' }`;
35537
35896
  }
35538
- return contractAddress;
35539
35897
  };
35540
35898
 
35541
35899
  // src/utils/grantFiles.ts
@@ -36091,6 +36449,42 @@ async function withSignatureCache(cache, walletAddress, typedData, signFn, ttlHo
36091
36449
  return signature;
36092
36450
  }
36093
36451
 
36452
+ // src/utils/signatureFormatter.ts
36453
+ var V_OFFSET_FOR_ETHEREUM = 27;
36454
+ function formatSignatureForContract(signature) {
36455
+ const cleanSig = signature.startsWith("0x") ? signature.slice(2) : signature;
36456
+ if (cleanSig.length !== 130) {
36457
+ return signature;
36458
+ }
36459
+ const vHex = cleanSig.slice(128, 130);
36460
+ const v = parseInt(vHex, 16);
36461
+ if (isNaN(v)) {
36462
+ return signature;
36463
+ }
36464
+ if (v < 27) {
36465
+ const adjustedV = (v + V_OFFSET_FOR_ETHEREUM).toString(16).padStart(2, "0");
36466
+ return `0x${cleanSig.slice(0, 128)}${adjustedV}`;
36467
+ }
36468
+ return signature;
36469
+ }
36470
+
36471
+ // src/utils/typedDataConverter.ts
36472
+ function toViemTypedDataDefinition(typedData) {
36473
+ const viemTypes = {};
36474
+ for (const [typeName, typeArray] of Object.entries(typedData.types)) {
36475
+ viemTypes[typeName] = typeArray.map((field) => ({
36476
+ name: field.name,
36477
+ type: field.type
36478
+ }));
36479
+ }
36480
+ return {
36481
+ domain: typedData.domain,
36482
+ types: viemTypes,
36483
+ primaryType: typedData.primaryType,
36484
+ message: typedData.message
36485
+ };
36486
+ }
36487
+
36094
36488
  // src/controllers/permissions.ts
36095
36489
  var PermissionsController = class {
36096
36490
  constructor(context) {
@@ -36131,31 +36525,32 @@ var PermissionsController = class {
36131
36525
  * ```
36132
36526
  */
36133
36527
  async grant(params) {
36134
- const txHash = await this.submitPermissionGrant(params);
36135
- return parseTransactionResult(this.context, txHash, "grant");
36528
+ const txHandle = await this.submitPermissionGrant(params);
36529
+ return await txHandle.waitForEvents();
36136
36530
  }
36137
36531
  /**
36138
- * Submits a permission grant transaction and returns the transaction hash immediately.
36532
+ * Submits a permission grant transaction and returns a handle for flexible result access.
36139
36533
  *
36140
- * This is the lower-level method that provides maximum control over transaction timing.
36141
- * Use this when you want to handle transaction confirmation and event parsing separately,
36142
- * or when submitting multiple transactions in batch.
36534
+ * @remarks
36535
+ * This lower-level method provides maximum control over transaction timing.
36536
+ * Returns a TransactionHandle that allows immediate hash access or optional event parsing.
36537
+ * Use this when handling multiple transactions or when you need granular control.
36143
36538
  *
36144
36539
  * @param params - The permission grant configuration object
36145
- * @returns Promise that resolves to the transaction hash when successfully submitted
36540
+ * @returns Promise resolving to TransactionHandle with hash and event parsing capabilities
36146
36541
  * @throws {RelayerError} When gasless transaction submission fails
36147
36542
  * @throws {SignatureError} When user rejects the signature request
36148
36543
  * @throws {SerializationError} When grant data cannot be serialized
36149
36544
  * @throws {BlockchainError} When permission grant preparation fails
36150
36545
  * @example
36151
36546
  * ```typescript
36152
- * // Submit transaction and handle confirmation later
36153
- * const txHash = await vana.permissions.submitPermissionGrant(params);
36154
- * console.log(`Transaction submitted: ${txHash}`);
36547
+ * // Submit transaction and get immediate hash access
36548
+ * const tx = await vana.permissions.submitPermissionGrant(params);
36549
+ * console.log(`Transaction submitted: ${tx.hash}`);
36155
36550
  *
36156
- * // Later, when you need the permission data:
36157
- * const result = await parseTransactionResult(context, txHash, 'grant');
36158
- * console.log(`Permission ID: ${result.permissionId}`);
36551
+ * // Optionally wait for and parse events
36552
+ * const eventData = await tx.waitForEvents();
36553
+ * console.log(`Permission ID: ${eventData.permissionId}`);
36159
36554
  * ```
36160
36555
  */
36161
36556
  async submitPermissionGrant(params) {
@@ -36213,12 +36608,18 @@ var PermissionsController = class {
36213
36608
  }
36214
36609
  }
36215
36610
  /**
36216
- * Internal method to complete the grant process after user confirmation.
36217
- * This is called by the confirm() function returned from prepareGrant().
36611
+ * Completes the grant process after user confirmation.
36612
+ *
36613
+ * @remarks
36614
+ * This internal method is called by the confirm() function returned from prepareGrant().
36615
+ * It handles IPFS upload, signature creation, and transaction submission.
36218
36616
  *
36219
36617
  * @param params - The permission grant parameters containing user and operation details
36220
36618
  * @param grantFile - The prepared grant file with permissions and metadata
36221
- * @returns Promise resolving to the transaction hash
36619
+ * @returns Promise resolving to TransactionHandle for flexible result access
36620
+ * @throws {BlockchainError} When permission grant confirmation fails
36621
+ * @throws {NetworkError} When IPFS upload fails
36622
+ * @throws {SignatureError} When user rejects the signature
36222
36623
  */
36223
36624
  async confirmGrantInternal(params, grantFile) {
36224
36625
  try {
@@ -36407,20 +36808,20 @@ var PermissionsController = class {
36407
36808
  2
36408
36809
  )
36409
36810
  );
36811
+ let hash;
36410
36812
  if (this.context.relayerCallbacks?.submitPermissionGrant) {
36411
- const jsonSafeTypedData = JSON.parse(
36412
- JSON.stringify(
36413
- typedData,
36414
- (_key, value) => typeof value === "bigint" ? value.toString() : value
36415
- )
36416
- );
36417
- return await this.context.relayerCallbacks.submitPermissionGrant(
36418
- jsonSafeTypedData,
36813
+ hash = await this.context.relayerCallbacks.submitPermissionGrant(
36814
+ typedData,
36419
36815
  signature
36420
36816
  );
36421
36817
  } else {
36422
- return await this.submitDirectTransaction(typedData, signature);
36818
+ hash = await this.submitDirectTransaction(typedData, signature);
36423
36819
  }
36820
+ return new TransactionHandle(
36821
+ this.context,
36822
+ hash,
36823
+ "grant"
36824
+ );
36424
36825
  } catch (error) {
36425
36826
  if (error instanceof RelayerError || error instanceof NetworkError || error instanceof UserRejectedRequestError || error instanceof SignatureError || error instanceof NonceError) {
36426
36827
  throw error;
@@ -36433,11 +36834,24 @@ var PermissionsController = class {
36433
36834
  }
36434
36835
  /**
36435
36836
  * Submits an already-signed trust server transaction to the blockchain.
36837
+ *
36838
+ * @remarks
36436
36839
  * This method extracts the trust server input from typed data and submits it directly.
36840
+ * Used internally by trust server methods after signature collection.
36437
36841
  *
36438
36842
  * @param typedData - The EIP-712 typed data for TrustServer
36439
- * @param signature - The user's signature
36440
- * @returns Promise resolving to the transaction hash
36843
+ * @param signature - The user's signature obtained via `signTypedData()`
36844
+ * @returns Promise resolving to TransactionHandle for transaction tracking
36845
+ * @throws {BlockchainError} When contract submission fails
36846
+ * @throws {NetworkError} When blockchain communication fails
36847
+ * @example
36848
+ * ```typescript
36849
+ * const txHandle = await vana.permissions.submitSignedTrustServer(
36850
+ * typedData,
36851
+ * "0x1234..."
36852
+ * );
36853
+ * const result = await txHandle.waitForEvents();
36854
+ * ```
36441
36855
  */
36442
36856
  async submitSignedTrustServer(typedData, signature) {
36443
36857
  try {
@@ -36445,10 +36859,15 @@ var PermissionsController = class {
36445
36859
  nonce: BigInt(typedData.message.nonce),
36446
36860
  serverId: typedData.message.serverId
36447
36861
  };
36448
- return await this.submitTrustServerTransaction(
36862
+ const hash = await this.submitTrustServerTransaction(
36449
36863
  trustServerInput,
36450
36864
  signature
36451
36865
  );
36866
+ return new TransactionHandle(
36867
+ this.context,
36868
+ hash,
36869
+ "trustServer"
36870
+ );
36452
36871
  } catch (error) {
36453
36872
  if (error instanceof RelayerError || error instanceof NetworkError || error instanceof UserRejectedRequestError || error instanceof SignatureError || error instanceof NonceError) {
36454
36873
  throw error;
@@ -36475,11 +36894,24 @@ var PermissionsController = class {
36475
36894
  }
36476
36895
  /**
36477
36896
  * Submits an already-signed add and trust server transaction to the blockchain.
36897
+ *
36898
+ * @remarks
36478
36899
  * This method extracts the add and trust server input from typed data and submits it directly.
36900
+ * Combines server registration and trust operations in a single transaction.
36479
36901
  *
36480
36902
  * @param typedData - The EIP-712 typed data for AddAndTrustServer
36481
- * @param signature - The user's signature
36482
- * @returns Promise resolving to the transaction hash
36903
+ * @param signature - The user's signature obtained via `signTypedData()`
36904
+ * @returns Promise resolving to TransactionHandle for transaction tracking
36905
+ * @throws {BlockchainError} When contract submission fails
36906
+ * @throws {NetworkError} When blockchain communication fails
36907
+ * @example
36908
+ * ```typescript
36909
+ * const txHandle = await vana.permissions.submitSignedAddAndTrustServer(
36910
+ * typedData,
36911
+ * "0x1234..."
36912
+ * );
36913
+ * const result = await txHandle.waitForEvents();
36914
+ * ```
36483
36915
  */
36484
36916
  async submitSignedAddAndTrustServer(typedData, signature) {
36485
36917
  try {
@@ -36489,10 +36921,15 @@ var PermissionsController = class {
36489
36921
  serverUrl: typedData.message.serverUrl,
36490
36922
  publicKey: typedData.message.publicKey
36491
36923
  };
36492
- return await this.submitAddAndTrustServerTransaction(
36924
+ const hash = await this.submitAddAndTrustServerTransaction(
36493
36925
  addAndTrustServerInput,
36494
36926
  signature
36495
36927
  );
36928
+ return new TransactionHandle(
36929
+ this.context,
36930
+ hash,
36931
+ "addAndTrustServer"
36932
+ );
36496
36933
  } catch (error) {
36497
36934
  if (error instanceof RelayerError || error instanceof NetworkError || error instanceof UserRejectedRequestError || error instanceof SignatureError || error instanceof NonceError) {
36498
36935
  throw error;
@@ -36505,28 +36942,41 @@ var PermissionsController = class {
36505
36942
  }
36506
36943
  /**
36507
36944
  * Submits an already-signed permission revoke transaction to the blockchain.
36945
+ *
36946
+ * @remarks
36508
36947
  * This method handles the revocation of previously granted permissions.
36948
+ * Used internally by revocation methods after signature collection.
36509
36949
  *
36510
36950
  * @param typedData - The EIP-712 typed data for PermissionRevoke
36511
- * @param signature - The user's signature
36512
- * @returns Promise resolving to the transaction hash
36951
+ * @param signature - The user's signature obtained via `signTypedData()`
36952
+ * @returns Promise resolving to TransactionHandle for transaction tracking
36953
+ * @throws {BlockchainError} When contract submission fails
36954
+ * @throws {NetworkError} When blockchain communication fails
36955
+ * @example
36956
+ * ```typescript
36957
+ * const txHandle = await vana.permissions.submitSignedRevoke(
36958
+ * typedData,
36959
+ * "0x1234..."
36960
+ * );
36961
+ * const result = await txHandle.waitForEvents();
36962
+ * ```
36513
36963
  */
36514
36964
  async submitSignedRevoke(typedData, signature) {
36515
36965
  try {
36966
+ let hash;
36516
36967
  if (this.context.relayerCallbacks?.submitPermissionRevoke) {
36517
- const jsonSafeTypedData = JSON.parse(
36518
- JSON.stringify(
36519
- typedData,
36520
- (_key, value) => typeof value === "bigint" ? value.toString() : value
36521
- )
36522
- );
36523
- return await this.context.relayerCallbacks.submitPermissionRevoke(
36524
- jsonSafeTypedData,
36968
+ hash = await this.context.relayerCallbacks.submitPermissionRevoke(
36969
+ typedData,
36525
36970
  signature
36526
36971
  );
36527
36972
  } else {
36528
- return await this.submitDirectRevokeTransaction(typedData, signature);
36973
+ hash = await this.submitDirectRevokeTransaction(typedData, signature);
36529
36974
  }
36975
+ return new TransactionHandle(
36976
+ this.context,
36977
+ hash,
36978
+ "revoke"
36979
+ );
36530
36980
  } catch (error) {
36531
36981
  if (error instanceof RelayerError || error instanceof NetworkError || error instanceof UserRejectedRequestError || error instanceof SignatureError || error instanceof NonceError) {
36532
36982
  throw error;
@@ -36539,22 +36989,41 @@ var PermissionsController = class {
36539
36989
  }
36540
36990
  /**
36541
36991
  * Submits an already-signed untrust server transaction to the blockchain.
36992
+ *
36993
+ * @remarks
36542
36994
  * This method handles the removal of trusted servers.
36995
+ * Used internally by untrust server methods after signature collection.
36543
36996
  *
36544
36997
  * @param typedData - The EIP-712 typed data for UntrustServer
36545
- * @param signature - The user's signature
36546
- * @returns Promise resolving to the transaction hash
36998
+ * @param signature - The user's signature obtained via `signTypedData()`
36999
+ * @returns Promise resolving to TransactionHandle for transaction tracking
37000
+ * @throws {BlockchainError} When contract submission fails
37001
+ * @throws {NetworkError} When blockchain communication fails
37002
+ * @example
37003
+ * ```typescript
37004
+ * const txHandle = await vana.permissions.submitSignedUntrustServer(
37005
+ * typedData,
37006
+ * "0x1234..."
37007
+ * );
37008
+ * const result = await txHandle.waitForEvents();
37009
+ * ```
36547
37010
  */
36548
37011
  async submitSignedUntrustServer(typedData, signature) {
36549
37012
  try {
37013
+ let hash;
36550
37014
  if (this.context.relayerCallbacks?.submitUntrustServer) {
36551
- return await this.context.relayerCallbacks.submitUntrustServer(
37015
+ hash = await this.context.relayerCallbacks.submitUntrustServer(
36552
37016
  typedData,
36553
37017
  signature
36554
37018
  );
36555
37019
  } else {
36556
- return await this.submitSignedUntrustTransaction(typedData, signature);
37020
+ hash = await this.submitSignedUntrustTransaction(typedData, signature);
36557
37021
  }
37022
+ return new TransactionHandle(
37023
+ this.context,
37024
+ hash,
37025
+ "untrustServer"
37026
+ );
36558
37027
  } catch (error) {
36559
37028
  if (error instanceof RelayerError || error instanceof NetworkError || error instanceof UserRejectedRequestError || error instanceof SignatureError || error instanceof NonceError) {
36560
37029
  throw error;
@@ -36568,9 +37037,14 @@ var PermissionsController = class {
36568
37037
  /**
36569
37038
  * Submits a signed transaction directly to the blockchain.
36570
37039
  *
37040
+ * @remarks
37041
+ * Internal method used when relayer callbacks are not available. Formats the signature
37042
+ * and submits the permission grant directly to the smart contract.
37043
+ *
36571
37044
  * @param typedData - The typed data structure for the permission grant
36572
37045
  * @param signature - The cryptographic signature authorizing the transaction
36573
37046
  * @returns Promise resolving to the transaction hash
37047
+ * @throws {BlockchainError} When contract submission fails
36574
37048
  */
36575
37049
  async submitDirectTransaction(typedData, signature) {
36576
37050
  const chainId = await this.context.walletClient.getChainId();
@@ -36595,11 +37069,12 @@ var PermissionsController = class {
36595
37069
  "\u{1F50D} Debug - Grant field length:",
36596
37070
  typedData.message.grant?.length || 0
36597
37071
  );
37072
+ const formattedSignature = formatSignatureForContract(signature);
36598
37073
  const txHash = await this.context.walletClient.writeContract({
36599
37074
  address: DataPortabilityPermissionsAddress,
36600
37075
  abi: DataPortabilityPermissionsAbi,
36601
37076
  functionName: "addPermission",
36602
- args: [permissionInput, signature],
37077
+ args: [permissionInput, formattedSignature],
36603
37078
  account: this.context.walletClient.account || await this.getUserAddress(),
36604
37079
  chain: this.context.walletClient.chain || null
36605
37080
  });
@@ -36630,8 +37105,8 @@ var PermissionsController = class {
36630
37105
  * ```
36631
37106
  */
36632
37107
  async revoke(params) {
36633
- const txHash = await this.submitPermissionRevoke(params);
36634
- return parseTransactionResult(this.context, txHash, "revoke");
37108
+ const txHandle = await this.submitPermissionRevoke(params);
37109
+ return await txHandle.waitForEvents();
36635
37110
  }
36636
37111
  /**
36637
37112
  * Submits a permission revocation transaction and returns the transaction hash immediately.
@@ -36673,7 +37148,11 @@ var PermissionsController = class {
36673
37148
  account: this.context.walletClient.account || await this.getUserAddress(),
36674
37149
  chain: this.context.walletClient.chain || null
36675
37150
  });
36676
- return txHash;
37151
+ return new TransactionHandle(
37152
+ this.context,
37153
+ txHash,
37154
+ "revoke"
37155
+ );
36677
37156
  } catch (error) {
36678
37157
  if (error instanceof Error) {
36679
37158
  if (error instanceof RelayerError || error instanceof UserRejectedRequestError || error instanceof SerializationError || error instanceof SignatureError || error instanceof NetworkError || error instanceof NonceError) {
@@ -36688,15 +37167,29 @@ var PermissionsController = class {
36688
37167
  }
36689
37168
  }
36690
37169
  /**
36691
- * Revokes a permission with a signature (gasless transaction).
37170
+ * Revokes a permission with a signature for gasless transactions.
37171
+ *
37172
+ * @remarks
37173
+ * This method creates an EIP-712 signature for permission revocation and submits
37174
+ * it either through relayer callbacks or directly to the blockchain. Provides
37175
+ * gasless revocation when relayer is configured.
36692
37176
  *
36693
37177
  * @param params - Parameters for revoking the permission
36694
- * @returns Promise resolving to transaction hash
37178
+ * @param params.permissionId - Permission identifier to revoke (accepts bigint, number, or string)
37179
+ * @returns Promise resolving to TransactionHandle for transaction tracking
36695
37180
  * @throws {BlockchainError} When chain ID is not available
36696
37181
  * @throws {NonceError} When retrieving user nonce fails
36697
37182
  * @throws {SignatureError} When user rejects the signature request
36698
37183
  * @throws {RelayerError} When gasless submission fails
36699
37184
  * @throws {PermissionError} When revocation fails for any other reason
37185
+ * @example
37186
+ * ```typescript
37187
+ * const txHandle = await vana.permissions.submitRevokeWithSignature({
37188
+ * permissionId: 123n
37189
+ * });
37190
+ * const result = await txHandle.waitForEvents();
37191
+ * console.log(`Permission ${result.permissionId} revoked`);
37192
+ * ```
36700
37193
  */
36701
37194
  async submitRevokeWithSignature(params) {
36702
37195
  try {
@@ -36720,14 +37213,20 @@ var PermissionsController = class {
36720
37213
  message: revokePermissionInput
36721
37214
  };
36722
37215
  const signature = await this.signTypedData(typedData);
37216
+ let hash;
36723
37217
  if (this.context.relayerCallbacks?.submitPermissionRevoke) {
36724
- return await this.context.relayerCallbacks.submitPermissionRevoke(
37218
+ hash = await this.context.relayerCallbacks.submitPermissionRevoke(
36725
37219
  typedData,
36726
37220
  signature
36727
37221
  );
36728
37222
  } else {
36729
- return await this.submitDirectRevokeTransaction(typedData, signature);
37223
+ hash = await this.submitDirectRevokeTransaction(typedData, signature);
36730
37224
  }
37225
+ return new TransactionHandle(
37226
+ this.context,
37227
+ hash,
37228
+ "revoke"
37229
+ );
36731
37230
  } catch (error) {
36732
37231
  throw new PermissionError(
36733
37232
  `Failed to revoke permission with signature: ${error instanceof Error ? error.message : "Unknown error"}`,
@@ -36759,6 +37258,18 @@ var PermissionsController = class {
36759
37258
  * const serversNonce = await this.getServersUserNonce();
36760
37259
  * ```
36761
37260
  */
37261
+ /**
37262
+ * @deprecated Use getPermissionsUserNonce() for permission operations or getServersUserNonce() for server operations
37263
+ *
37264
+ * Retrieves the user's current nonce from the DataPortabilityServers contract.
37265
+ *
37266
+ * @remarks
37267
+ * This method is deprecated in favor of more specific nonce methods that target
37268
+ * the appropriate contract for the operation being performed.
37269
+ *
37270
+ * @returns Promise resolving to the user's current nonce as a bigint
37271
+ * @throws {NonceError} When retrieving the nonce fails
37272
+ */
36762
37273
  async getUserNonce() {
36763
37274
  try {
36764
37275
  const userAddress = await this.getUserAddress();
@@ -36795,6 +37306,16 @@ var PermissionsController = class {
36795
37306
  * console.log(`Current servers nonce: ${nonce}`);
36796
37307
  * ```
36797
37308
  */
37309
+ /**
37310
+ * Retrieves the user's current nonce from the DataPortabilityServers contract.
37311
+ *
37312
+ * @remarks
37313
+ * Used for server-related operations (trust/untrust) to prevent replay attacks.
37314
+ * The nonce must be incremented with each server operation.
37315
+ *
37316
+ * @returns Promise resolving to the user's current nonce as a bigint
37317
+ * @throws {NonceError} When retrieving the nonce fails
37318
+ */
36798
37319
  async getServersUserNonce() {
36799
37320
  try {
36800
37321
  const userAddress = await this.getUserAddress();
@@ -36831,6 +37352,16 @@ var PermissionsController = class {
36831
37352
  * console.log(`Current permissions nonce: ${nonce}`);
36832
37353
  * ```
36833
37354
  */
37355
+ /**
37356
+ * Retrieves the user's current nonce from the DataPortabilityPermissions contract.
37357
+ *
37358
+ * @remarks
37359
+ * Used for permission-related operations (grant/revoke) to prevent replay attacks.
37360
+ * The nonce must be incremented with each permission operation.
37361
+ *
37362
+ * @returns Promise resolving to the user's current nonce as a bigint
37363
+ * @throws {NonceError} When retrieving the nonce fails
37364
+ */
36834
37365
  async getPermissionsUserNonce() {
36835
37366
  try {
36836
37367
  const userAddress = await this.getUserAddress();
@@ -37005,9 +37536,13 @@ var PermissionsController = class {
37005
37536
  walletAddress,
37006
37537
  typedData,
37007
37538
  async () => {
37008
- return await this.context.walletClient.signTypedData(
37009
- typedData
37010
- );
37539
+ const viemCompatibleTypedData = toViemTypedDataDefinition(typedData);
37540
+ return await this.context.walletClient.signTypedData({
37541
+ ...viemCompatibleTypedData,
37542
+ // Non-null assertion is safe here because getUserAddress() above ensures account exists
37543
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
37544
+ account: this.context.walletClient.account
37545
+ });
37011
37546
  }
37012
37547
  );
37013
37548
  } catch (error) {
@@ -37232,7 +37767,11 @@ var PermissionsController = class {
37232
37767
  account: this.context.walletClient.account || await this.getUserAddress(),
37233
37768
  chain: this.context.walletClient.chain || null
37234
37769
  });
37235
- return txHash;
37770
+ return new TransactionHandle(
37771
+ this.context,
37772
+ txHash,
37773
+ "addAndTrustServer"
37774
+ );
37236
37775
  } catch (error) {
37237
37776
  if (error instanceof Error && error.message.includes("rejected")) {
37238
37777
  throw new UserRejectedRequestError();
@@ -37266,7 +37805,11 @@ var PermissionsController = class {
37266
37805
  account: this.context.walletClient.account || await this.getUserAddress(),
37267
37806
  chain: this.context.walletClient.chain || null
37268
37807
  });
37269
- return txHash;
37808
+ return new TransactionHandle(
37809
+ this.context,
37810
+ txHash,
37811
+ "trustServer"
37812
+ );
37270
37813
  } catch (error) {
37271
37814
  if (error instanceof Error && error.message.includes("rejected")) {
37272
37815
  throw new UserRejectedRequestError();
@@ -37281,7 +37824,7 @@ var PermissionsController = class {
37281
37824
  * Adds and trusts a server using a signature (gasless transaction).
37282
37825
  *
37283
37826
  * @param params - Parameters for adding and trusting the server
37284
- * @returns Promise resolving to transaction hash
37827
+ * @returns Promise resolving to TransactionHandle with ServerTrustResult event data
37285
37828
  */
37286
37829
  async submitAddAndTrustServerWithSignature(params) {
37287
37830
  try {
@@ -37303,21 +37846,25 @@ var PermissionsController = class {
37303
37846
  domain: typedData.domain,
37304
37847
  typedDataMessage: typedData.message
37305
37848
  });
37306
- const signature = await this.signTypedData(
37307
- typedData
37308
- );
37849
+ const signature = await this.signTypedData(typedData);
37309
37850
  console.debug("\u{1F50D} Generated signature:", signature);
37851
+ let hash;
37310
37852
  if (this.context.relayerCallbacks?.submitAddAndTrustServer) {
37311
- return await this.context.relayerCallbacks.submitAddAndTrustServer(
37853
+ hash = await this.context.relayerCallbacks.submitAddAndTrustServer(
37312
37854
  typedData,
37313
37855
  signature
37314
37856
  );
37315
37857
  } else {
37316
- return await this.submitAddAndTrustServerTransaction(
37858
+ hash = await this.submitAddAndTrustServerTransaction(
37317
37859
  addAndTrustServerInput,
37318
37860
  signature
37319
37861
  );
37320
37862
  }
37863
+ return new TransactionHandle(
37864
+ this.context,
37865
+ hash,
37866
+ "addAndTrustServer"
37867
+ );
37321
37868
  } catch (error) {
37322
37869
  if (error instanceof Error) {
37323
37870
  if (error instanceof RelayerError || error instanceof UserRejectedRequestError || error instanceof SerializationError || error instanceof SignatureError || error instanceof NetworkError || error instanceof NonceError) {
@@ -37354,20 +37901,24 @@ var PermissionsController = class {
37354
37901
  serverId: params.serverId
37355
37902
  };
37356
37903
  const typedData = await this.composeTrustServerMessage(trustServerInput);
37357
- const signature = await this.signTypedData(
37358
- typedData
37359
- );
37904
+ const signature = await this.signTypedData(typedData);
37905
+ let hash;
37360
37906
  if (this.context.relayerCallbacks?.submitTrustServer) {
37361
- return await this.context.relayerCallbacks.submitTrustServer(
37907
+ hash = await this.context.relayerCallbacks.submitTrustServer(
37362
37908
  typedData,
37363
37909
  signature
37364
37910
  );
37365
37911
  } else {
37366
- return await this.submitTrustServerTransaction(
37912
+ hash = await this.submitTrustServerTransaction(
37367
37913
  trustServerInput,
37368
37914
  signature
37369
37915
  );
37370
37916
  }
37917
+ return new TransactionHandle(
37918
+ this.context,
37919
+ hash,
37920
+ "trustServer"
37921
+ );
37371
37922
  } catch (error) {
37372
37923
  if (error instanceof Error) {
37373
37924
  if (error instanceof RelayerError || error instanceof UserRejectedRequestError || error instanceof SerializationError || error instanceof SignatureError || error instanceof NetworkError || error instanceof NonceError) {
@@ -37387,6 +37938,17 @@ var PermissionsController = class {
37387
37938
  * @param params - The untrust server parameters containing server details
37388
37939
  * @returns Promise resolving to the transaction hash
37389
37940
  */
37941
+ /**
37942
+ * Submits an untrust server transaction directly to the blockchain.
37943
+ *
37944
+ * @remarks
37945
+ * Internal method used for direct blockchain submission of untrust server operations
37946
+ * when relayer callbacks are not available.
37947
+ *
37948
+ * @param params - The untrust server parameters
37949
+ * @returns Promise resolving to TransactionHandle for transaction tracking
37950
+ * @throws {BlockchainError} When contract submission fails
37951
+ */
37390
37952
  async submitDirectUntrustTransaction(params) {
37391
37953
  try {
37392
37954
  const chainId = await this.context.walletClient.getChainId();
@@ -37403,7 +37965,11 @@ var PermissionsController = class {
37403
37965
  account: this.context.walletClient.account || await this.getUserAddress(),
37404
37966
  chain: this.context.walletClient.chain || null
37405
37967
  });
37406
- return txHash;
37968
+ return new TransactionHandle(
37969
+ this.context,
37970
+ txHash,
37971
+ "untrustServer"
37972
+ );
37407
37973
  } catch (error) {
37408
37974
  if (error instanceof Error && error.message.includes("rejected")) {
37409
37975
  throw new UserRejectedRequestError();
@@ -37470,20 +38036,21 @@ var PermissionsController = class {
37470
38036
  serverId: params.serverId
37471
38037
  };
37472
38038
  const typedData = await this.composeUntrustServerMessage(untrustServerInput);
37473
- const signature = await this.signTypedData(
37474
- typedData
37475
- );
38039
+ const signature = await this.signTypedData(typedData);
38040
+ let hash;
37476
38041
  if (this.context.relayerCallbacks?.submitUntrustServer) {
37477
- return await this.context.relayerCallbacks.submitUntrustServer(
38042
+ hash = await this.context.relayerCallbacks.submitUntrustServer(
37478
38043
  typedData,
37479
38044
  signature
37480
38045
  );
37481
38046
  } else {
37482
- return await this.submitSignedUntrustTransaction(
37483
- typedData,
37484
- signature
37485
- );
38047
+ hash = await this.submitSignedUntrustTransaction(typedData, signature);
37486
38048
  }
38049
+ return new TransactionHandle(
38050
+ this.context,
38051
+ hash,
38052
+ "untrustServer"
38053
+ );
37487
38054
  } catch (error) {
37488
38055
  if (error instanceof Error) {
37489
38056
  if (error instanceof RelayerError || error instanceof UserRejectedRequestError || error instanceof SerializationError || error instanceof SignatureError || error instanceof NetworkError || error instanceof NonceError) {
@@ -37607,18 +38174,19 @@ var PermissionsController = class {
37607
38174
  };
37608
38175
  }
37609
38176
  const endIndex = Math.min(offset + limit, total);
37610
- const serverPromises = [];
38177
+ const serverIdCalls = [];
37611
38178
  for (let i = offset; i < endIndex; i++) {
37612
- const promise = this.context.publicClient.readContract({
38179
+ serverIdCalls.push({
37613
38180
  address: DataPortabilityServersAddress,
37614
38181
  abi: DataPortabilityServersAbi,
37615
38182
  functionName: "userServerIdsAt",
37616
38183
  args: [user, BigInt(i)]
37617
38184
  });
37618
- serverPromises.push(promise);
37619
38185
  }
37620
- const serverIds = await Promise.all(serverPromises);
37621
- const servers = serverIds.map((id) => Number(id));
38186
+ const serverIdResults = await gasAwareMulticall(this.context.publicClient, {
38187
+ contracts: serverIdCalls
38188
+ });
38189
+ const servers = serverIdResults.map((result) => Number(result)).filter((id) => id > 0);
37622
38190
  return {
37623
38191
  servers,
37624
38192
  total,
@@ -37643,35 +38211,51 @@ var PermissionsController = class {
37643
38211
  async getTrustedServersWithInfo(options = {}) {
37644
38212
  try {
37645
38213
  const paginatedResult = await this.getTrustedServersPaginated(options);
37646
- const serverInfoPromises = paginatedResult.servers.map(
37647
- async (serverId, _index) => {
37648
- try {
37649
- const serverInfo = await this.getServerInfo(BigInt(serverId));
37650
- return {
37651
- id: BigInt(serverId),
37652
- owner: serverInfo.owner,
37653
- serverAddress: serverInfo.serverAddress,
37654
- publicKey: serverInfo.publicKey,
37655
- url: serverInfo.url,
37656
- startBlock: 0n,
37657
- // We don't have this info from the old method structure
37658
- endBlock: 0n
37659
- // 0 means still active
37660
- };
37661
- } catch {
37662
- return {
37663
- id: BigInt(serverId),
37664
- owner: "0x0000000000000000000000000000000000000000",
37665
- serverAddress: "0x0000000000000000000000000000000000000000",
37666
- publicKey: "",
37667
- url: "",
37668
- startBlock: 0n,
37669
- endBlock: 0n
37670
- };
37671
- }
37672
- }
38214
+ const chainId = await this.context.publicClient.getChainId();
38215
+ const DataPortabilityServersAddress = getContractAddress(
38216
+ chainId,
38217
+ "DataPortabilityServers"
38218
+ );
38219
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
38220
+ const serverInfoCalls = paginatedResult.servers.map(
38221
+ (serverId) => ({
38222
+ address: DataPortabilityServersAddress,
38223
+ abi: DataPortabilityServersAbi,
38224
+ functionName: "servers",
38225
+ args: [BigInt(serverId)]
38226
+ })
37673
38227
  );
37674
- return await Promise.all(serverInfoPromises);
38228
+ const serverInfoResults = await gasAwareMulticall(this.context.publicClient, {
38229
+ contracts: serverInfoCalls,
38230
+ allowFailure: true
38231
+ });
38232
+ return serverInfoResults.map((result, index) => {
38233
+ const serverId = paginatedResult.servers[index];
38234
+ if (result.status === "success" && result.result) {
38235
+ const serverInfo = result.result;
38236
+ return {
38237
+ id: BigInt(serverId),
38238
+ owner: serverInfo.owner,
38239
+ serverAddress: serverInfo.serverAddress,
38240
+ publicKey: serverInfo.publicKey,
38241
+ url: serverInfo.url,
38242
+ startBlock: 0n,
38243
+ // We don't have this info from the old method structure
38244
+ endBlock: 0n
38245
+ // 0 means still active
38246
+ };
38247
+ } else {
38248
+ return {
38249
+ id: BigInt(serverId),
38250
+ owner: "0x0000000000000000000000000000000000000000",
38251
+ serverAddress: "0x0000000000000000000000000000000000000000",
38252
+ publicKey: "",
38253
+ url: "",
38254
+ startBlock: 0n,
38255
+ endBlock: 0n
38256
+ };
38257
+ }
38258
+ });
37675
38259
  } catch (error) {
37676
38260
  throw new BlockchainError(
37677
38261
  `Failed to get trusted servers with info: ${error instanceof Error ? error.message : "Unknown error"}`,
@@ -37682,9 +38266,28 @@ var PermissionsController = class {
37682
38266
  /**
37683
38267
  * Gets server information for multiple servers efficiently.
37684
38268
  *
37685
- * @param serverIds - Array of server IDs to query
37686
- * @returns Promise resolving to batch result with successes and failures
38269
+ * @remarks
38270
+ * This method uses multicall to fetch information for multiple servers in a single
38271
+ * blockchain call, improving performance when querying many servers. Failed lookups
38272
+ * are returned separately for error handling.
38273
+ *
38274
+ * @param serverIds - Array of numeric server IDs to query
38275
+ * @returns Promise resolving to batch result containing successful lookups and failed IDs
37687
38276
  * @throws {BlockchainError} When reading from contract fails or chain is unavailable
38277
+ * @example
38278
+ * ```typescript
38279
+ * const result = await vana.permissions.getServerInfoBatch([1, 2, 3, 999]);
38280
+ *
38281
+ * // Process successful lookups
38282
+ * result.servers.forEach((server, id) => {
38283
+ * console.log(`Server ${id}: ${server.url}`);
38284
+ * });
38285
+ *
38286
+ * // Handle failed lookups
38287
+ * if (result.failed.length > 0) {
38288
+ * console.log(`Failed to fetch: ${result.failed.join(', ')}`);
38289
+ * }
38290
+ * ```
37688
38291
  */
37689
38292
  async getServerInfoBatch(serverIds) {
37690
38293
  if (serverIds.length === 0) {
@@ -37700,14 +38303,22 @@ var PermissionsController = class {
37700
38303
  "DataPortabilityServers"
37701
38304
  );
37702
38305
  const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
37703
- const serverInfoPromises = serverIds.map(async (serverId) => {
37704
- try {
37705
- const serverInfo = await this.context.publicClient.readContract({
37706
- address: DataPortabilityServersAddress,
37707
- abi: DataPortabilityServersAbi,
37708
- functionName: "servers",
37709
- args: [BigInt(serverId)]
37710
- });
38306
+ const serverInfoCalls = serverIds.map(
38307
+ (serverId) => ({
38308
+ address: DataPortabilityServersAddress,
38309
+ abi: DataPortabilityServersAbi,
38310
+ functionName: "servers",
38311
+ args: [BigInt(serverId)]
38312
+ })
38313
+ );
38314
+ const serverInfoResults = await gasAwareMulticall(this.context.publicClient, {
38315
+ contracts: serverInfoCalls,
38316
+ allowFailure: true
38317
+ });
38318
+ const results = serverInfoResults.map((result, index) => {
38319
+ const serverId = serverIds[index];
38320
+ if (result.status === "success" && result.result) {
38321
+ const serverInfo = result.result;
37711
38322
  const server = {
37712
38323
  id: Number(serverInfo.id),
37713
38324
  owner: serverInfo.owner,
@@ -37716,11 +38327,10 @@ var PermissionsController = class {
37716
38327
  publicKey: serverInfo.publicKey
37717
38328
  };
37718
38329
  return { serverId, server, success: true };
37719
- } catch {
38330
+ } else {
37720
38331
  return { serverId, server: null, success: false };
37721
38332
  }
37722
38333
  });
37723
- const results = await Promise.all(serverInfoPromises);
37724
38334
  const servers = /* @__PURE__ */ new Map();
37725
38335
  const failed = [];
37726
38336
  for (const result of results) {
@@ -37741,9 +38351,24 @@ var PermissionsController = class {
37741
38351
  /**
37742
38352
  * Checks whether a specific server is trusted by a user.
37743
38353
  *
37744
- * @param serverId - Server ID to check (numeric)
38354
+ * @remarks
38355
+ * This method queries the user's trusted server list and checks if the specified
38356
+ * server is present. Returns both the trust status and the index in the trust list
38357
+ * if trusted.
38358
+ *
38359
+ * @param serverId - Numeric server ID to check
37745
38360
  * @param userAddress - Optional user address (defaults to current user)
37746
- * @returns Promise resolving to server trust status
38361
+ * @returns Promise resolving to server trust status with trust index if applicable
38362
+ * @throws {BlockchainError} When reading from contract fails
38363
+ * @example
38364
+ * ```typescript
38365
+ * const status = await vana.permissions.checkServerTrustStatus(1);
38366
+ * if (status.isTrusted) {
38367
+ * console.log(`Server is trusted at index ${status.trustIndex}`);
38368
+ * } else {
38369
+ * console.log('Server is not trusted');
38370
+ * }
38371
+ * ```
37747
38372
  */
37748
38373
  async checkServerTrustStatus(serverId, userAddress) {
37749
38374
  try {
@@ -37767,6 +38392,10 @@ var PermissionsController = class {
37767
38392
  /**
37768
38393
  * Composes EIP-712 typed data for AddAndTrustServer.
37769
38394
  *
38395
+ * @remarks
38396
+ * Creates the complete typed data structure required for EIP-712 signature generation
38397
+ * when adding and trusting a new server in a single transaction.
38398
+ *
37770
38399
  * @param input - The add and trust server input data containing server details
37771
38400
  * @returns Promise resolving to the typed data structure for server add and trust
37772
38401
  */
@@ -37870,6 +38499,7 @@ var PermissionsController = class {
37870
38499
  },
37871
38500
  signature
37872
38501
  });
38502
+ const formattedSignature = formatSignatureForContract(signature);
37873
38503
  const txHash = await this.context.walletClient.writeContract({
37874
38504
  address: DataPortabilityServersAddress,
37875
38505
  abi: DataPortabilityServersAbi,
@@ -37881,7 +38511,7 @@ var PermissionsController = class {
37881
38511
  publicKey: addAndTrustServerInput.publicKey,
37882
38512
  serverUrl: addAndTrustServerInput.serverUrl
37883
38513
  },
37884
- signature
38514
+ formattedSignature
37885
38515
  ],
37886
38516
  account: this.context.walletClient.account || await this.getUserAddress(),
37887
38517
  chain: this.context.walletClient.chain || null
@@ -37902,6 +38532,7 @@ var PermissionsController = class {
37902
38532
  "DataPortabilityServers"
37903
38533
  );
37904
38534
  const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
38535
+ const formattedSignature = formatSignatureForContract(signature);
37905
38536
  const txHash = await this.context.walletClient.writeContract({
37906
38537
  address: DataPortabilityServersAddress,
37907
38538
  abi: DataPortabilityServersAbi,
@@ -37911,7 +38542,7 @@ var PermissionsController = class {
37911
38542
  nonce: trustServerInput.nonce,
37912
38543
  serverId: BigInt(trustServerInput.serverId)
37913
38544
  },
37914
- signature
38545
+ formattedSignature
37915
38546
  ],
37916
38547
  account: this.context.walletClient.account || await this.getUserAddress(),
37917
38548
  chain: this.context.walletClient.chain || null
@@ -37932,12 +38563,13 @@ var PermissionsController = class {
37932
38563
  "DataPortabilityPermissions"
37933
38564
  );
37934
38565
  const DataPortabilityPermissionsAbi = getAbi("DataPortabilityPermissions");
38566
+ const formattedSignature = formatSignatureForContract(signature);
37935
38567
  const txHash = await this.context.walletClient.writeContract({
37936
38568
  address: DataPortabilityPermissionsAddress,
37937
38569
  abi: DataPortabilityPermissionsAbi,
37938
38570
  functionName: "revokePermissionWithSignature",
37939
38571
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
37940
- args: [typedData.message, signature],
38572
+ args: [typedData.message, formattedSignature],
37941
38573
  account: this.context.walletClient.account || await this.getUserAddress(),
37942
38574
  chain: this.context.walletClient.chain || null
37943
38575
  });
@@ -37957,12 +38589,13 @@ var PermissionsController = class {
37957
38589
  "DataPortabilityServers"
37958
38590
  );
37959
38591
  const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
38592
+ const formattedSignature = formatSignatureForContract(signature);
37960
38593
  const txHash = await this.context.walletClient.writeContract({
37961
38594
  address: DataPortabilityServersAddress,
37962
38595
  abi: DataPortabilityServersAbi,
37963
38596
  functionName: "untrustServerWithSignature",
37964
38597
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
37965
- args: [typedData.message, signature],
38598
+ args: [typedData.message, formattedSignature],
37966
38599
  account: this.context.walletClient.account || await this.getUserAddress(),
37967
38600
  chain: this.context.walletClient.chain || null
37968
38601
  });
@@ -38011,7 +38644,11 @@ var PermissionsController = class {
38011
38644
  account: this.context.walletClient.account || await this.getUserAddress(),
38012
38645
  chain: this.context.walletClient.chain || null
38013
38646
  });
38014
- return txHash;
38647
+ return new TransactionHandle(
38648
+ this.context,
38649
+ txHash,
38650
+ "registerGrantee"
38651
+ );
38015
38652
  }
38016
38653
  /**
38017
38654
  * Registers a grantee with a signature (gasless transaction)
@@ -38038,7 +38675,15 @@ var PermissionsController = class {
38038
38675
  };
38039
38676
  const typedData = await this.buildRegisterGranteeTypedData(registerGranteeInput);
38040
38677
  const signature = await this.signTypedData(typedData);
38041
- return this.submitSignedRegisterGranteeTransaction(typedData, signature);
38678
+ const hash = await this.submitSignedRegisterGranteeTransaction(
38679
+ typedData,
38680
+ signature
38681
+ );
38682
+ return new TransactionHandle(
38683
+ this.context,
38684
+ hash,
38685
+ "registerGrantee"
38686
+ );
38042
38687
  }
38043
38688
  /**
38044
38689
  * Submits a signed register grantee transaction via relayer
@@ -38053,7 +38698,15 @@ var PermissionsController = class {
38053
38698
  * ```
38054
38699
  */
38055
38700
  async submitSignedRegisterGrantee(typedData, signature) {
38056
- return this.submitSignedRegisterGranteeTransaction(typedData, signature);
38701
+ const hash = await this.submitSignedRegisterGranteeTransaction(
38702
+ typedData,
38703
+ signature
38704
+ );
38705
+ return new TransactionHandle(
38706
+ this.context,
38707
+ hash,
38708
+ "registerGrantee"
38709
+ );
38057
38710
  }
38058
38711
  /**
38059
38712
  * Retrieves all registered grantees from the DataPortabilityGrantees contract.
@@ -39039,7 +39692,11 @@ var PermissionsController = class {
39039
39692
  chain: this.context.walletClient.chain,
39040
39693
  account: this.context.walletClient.account || null
39041
39694
  });
39042
- return hash;
39695
+ return new TransactionHandle(
39696
+ this.context,
39697
+ hash,
39698
+ "updateServer"
39699
+ );
39043
39700
  } catch (error) {
39044
39701
  throw new BlockchainError(
39045
39702
  `Failed to update server: ${error instanceof Error ? error.message : "Unknown error"}`,
@@ -39179,10 +39836,14 @@ var PermissionsController = class {
39179
39836
  }
39180
39837
  }
39181
39838
  /**
39182
- * Submit permission with signature to the blockchain
39839
+ * Submit permission with signature to the blockchain (supports gasless transactions)
39183
39840
  *
39184
39841
  * @param params - Parameters for adding permission
39185
39842
  * @returns Promise resolving to transaction hash
39843
+ * @throws {RelayerError} When gasless transaction submission fails
39844
+ * @throws {SignatureError} When user rejects the signature request
39845
+ * @throws {BlockchainError} When permission addition fails
39846
+ * @throws {NetworkError} When network communication fails
39186
39847
  */
39187
39848
  async submitAddPermission(params) {
39188
39849
  try {
@@ -39199,44 +39860,66 @@ var PermissionsController = class {
39199
39860
  };
39200
39861
  const typedData = await this.composeServerFilesAndPermissionMessage(addPermissionInput);
39201
39862
  const signature = await this.signTypedData(typedData);
39202
- const chainId = await this.context.walletClient.getChainId();
39203
- const DataPortabilityPermissionsAddress = getContractAddress(
39204
- chainId,
39205
- "DataPortabilityPermissions"
39206
- );
39207
- const DataPortabilityPermissionsAbi = getAbi(
39208
- "DataPortabilityPermissions"
39863
+ return await this.submitSignedAddPermission(typedData, signature);
39864
+ } catch (error) {
39865
+ if (error instanceof RelayerError || error instanceof UserRejectedRequestError || error instanceof SerializationError || error instanceof SignatureError || error instanceof NetworkError || error instanceof NonceError) {
39866
+ throw error;
39867
+ }
39868
+ throw new BlockchainError(
39869
+ `Failed to add permission: ${error instanceof Error ? error.message : "Unknown error"}`,
39870
+ error
39209
39871
  );
39210
- const hash = await this.context.walletClient.writeContract({
39211
- address: DataPortabilityPermissionsAddress,
39212
- abi: DataPortabilityPermissionsAbi,
39213
- functionName: "addPermission",
39214
- args: [
39215
- {
39216
- nonce: addPermissionInput.nonce,
39217
- granteeId: addPermissionInput.granteeId,
39218
- grant: addPermissionInput.grant,
39219
- fileIds: []
39220
- // Note: This should be handled differently for addPermission vs addServerFilesAndPermissions
39221
- },
39872
+ }
39873
+ }
39874
+ /**
39875
+ * Submits an already-signed add permission transaction to the blockchain.
39876
+ * This method supports both relayer-based gasless transactions and direct transactions.
39877
+ *
39878
+ * @param typedData - The EIP-712 typed data for AddPermission
39879
+ * @param signature - The user's signature
39880
+ * @returns Promise resolving to TransactionHandle with PermissionGrantResult event data
39881
+ * @throws {RelayerError} When gasless transaction submission fails
39882
+ * @throws {BlockchainError} When permission addition fails
39883
+ * @throws {NetworkError} When network communication fails
39884
+ */
39885
+ async submitSignedAddPermission(typedData, signature) {
39886
+ try {
39887
+ let hash;
39888
+ if (this.context.relayerCallbacks?.submitAddPermission) {
39889
+ hash = await this.context.relayerCallbacks.submitAddPermission(
39890
+ typedData,
39222
39891
  signature
39223
- ],
39224
- chain: this.context.walletClient.chain,
39225
- account: this.context.walletClient.account || null
39226
- });
39227
- return hash;
39892
+ );
39893
+ } else {
39894
+ hash = await this.submitDirectAddPermissionTransaction(
39895
+ typedData,
39896
+ signature
39897
+ );
39898
+ }
39899
+ return new TransactionHandle(
39900
+ this.context,
39901
+ hash,
39902
+ "addServerFilesAndPermissions"
39903
+ );
39228
39904
  } catch (error) {
39905
+ if (error instanceof RelayerError || error instanceof NetworkError || error instanceof UserRejectedRequestError || error instanceof SignatureError || error instanceof NonceError) {
39906
+ throw error;
39907
+ }
39229
39908
  throw new BlockchainError(
39230
- `Failed to add permission: ${error instanceof Error ? error.message : "Unknown error"}`,
39909
+ `Add permission submission failed: ${error instanceof Error ? error.message : "Unknown error"}`,
39231
39910
  error
39232
39911
  );
39233
39912
  }
39234
39913
  }
39235
39914
  /**
39236
- * Submit server files and permissions with signature to the blockchain
39915
+ * Submit server files and permissions with signature to the blockchain (supports gasless transactions)
39237
39916
  *
39238
39917
  * @param params - Parameters for adding server files and permissions
39239
39918
  * @returns Promise resolving to transaction hash
39919
+ * @throws {RelayerError} When gasless transaction submission fails
39920
+ * @throws {SignatureError} When user rejects the signature request
39921
+ * @throws {BlockchainError} When server files and permissions addition fails
39922
+ * @throws {NetworkError} When network communication fails
39240
39923
  */
39241
39924
  async submitAddServerFilesAndPermissions(params) {
39242
39925
  try {
@@ -39255,27 +39938,88 @@ var PermissionsController = class {
39255
39938
  serverFilesAndPermissionInput
39256
39939
  );
39257
39940
  const signature = await this.signTypedData(typedData);
39258
- const chainId = await this.context.walletClient.getChainId();
39259
- const DataPortabilityPermissionsAddress = getContractAddress(
39260
- chainId,
39261
- "DataPortabilityPermissions"
39941
+ return await this.submitSignedAddServerFilesAndPermissions(
39942
+ typedData,
39943
+ signature
39262
39944
  );
39263
- const DataPortabilityPermissionsAbi = getAbi(
39264
- "DataPortabilityPermissions"
39945
+ } catch (error) {
39946
+ if (error instanceof RelayerError || error instanceof UserRejectedRequestError || error instanceof SerializationError || error instanceof SignatureError || error instanceof NetworkError || error instanceof NonceError) {
39947
+ throw error;
39948
+ }
39949
+ throw new BlockchainError(
39950
+ `Failed to add server files and permissions: ${error instanceof Error ? error.message : "Unknown error"}`,
39951
+ error
39265
39952
  );
39266
- const hash = await this.context.walletClient.writeContract({
39267
- address: DataPortabilityPermissionsAddress,
39268
- abi: DataPortabilityPermissionsAbi,
39269
- functionName: "addServerFilesAndPermissions",
39270
- // @ts-expect-error - Complex nested array types cause compatibility issues with viem's generated types
39271
- args: [serverFilesAndPermissionInput, signature],
39272
- chain: this.context.walletClient.chain,
39273
- account: this.context.walletClient.account || null
39953
+ }
39954
+ }
39955
+ /**
39956
+ * Submits an already-signed add server files and permissions transaction to the blockchain.
39957
+ *
39958
+ * @remarks
39959
+ * This method returns a TransactionHandle that provides immediate access to the transaction hash
39960
+ * while allowing lazy-loaded access to parsed event data. Use `waitForEvents()` to retrieve
39961
+ * the permission ID and other event details after transaction confirmation.
39962
+ *
39963
+ * @param typedData - The EIP-712 typed data for AddServerFilesAndPermissions
39964
+ * @param signature - The user's signature
39965
+ * @returns TransactionHandle with immediate hash access and optional event parsing
39966
+ * @throws {RelayerError} When gasless transaction submission fails
39967
+ * @throws {BlockchainError} When server files and permissions addition fails
39968
+ * @throws {NetworkError} When network communication fails
39969
+ *
39970
+ * @example
39971
+ * ```typescript
39972
+ * const tx = await vana.permissions.submitSignedAddServerFilesAndPermissions(
39973
+ * typedData,
39974
+ * signature
39975
+ * );
39976
+ * console.log(`Transaction submitted: ${tx.hash}`);
39977
+ *
39978
+ * // Wait for confirmation and get the permission ID
39979
+ * const { permissionId } = await tx.waitForEvents();
39980
+ * console.log(`Permission created with ID: ${permissionId}`);
39981
+ * ```
39982
+ */
39983
+ async submitSignedAddServerFilesAndPermissions(typedData, signature) {
39984
+ try {
39985
+ console.debug("\u{1F50D} submitSignedAddServerFilesAndPermissions Debug Info:", {
39986
+ hasRelayerCallbacks: !!this.context.relayerCallbacks,
39987
+ hasSubmitMethod: !!this.context.relayerCallbacks?.submitAddServerFilesAndPermissions,
39988
+ availableRelayerMethods: this.context.relayerCallbacks ? Object.keys(this.context.relayerCallbacks) : []
39274
39989
  });
39275
- return hash;
39990
+ if (this.context.relayerCallbacks?.submitAddServerFilesAndPermissions) {
39991
+ console.debug(
39992
+ "\u{1F680} Using relayer for submitAddServerFilesAndPermissions"
39993
+ );
39994
+ const hash = await this.context.relayerCallbacks.submitAddServerFilesAndPermissions(
39995
+ typedData,
39996
+ signature
39997
+ );
39998
+ return new TransactionHandle(
39999
+ this.context,
40000
+ hash,
40001
+ "addServerFilesAndPermissions"
40002
+ );
40003
+ } else {
40004
+ console.debug(
40005
+ "\u{1F4DD} Using direct transaction for submitAddServerFilesAndPermissions"
40006
+ );
40007
+ const hash = await this.submitDirectAddServerFilesAndPermissionsTransaction(
40008
+ typedData,
40009
+ signature
40010
+ );
40011
+ return new TransactionHandle(
40012
+ this.context,
40013
+ hash,
40014
+ "addServerFilesAndPermissions"
40015
+ );
40016
+ }
39276
40017
  } catch (error) {
40018
+ if (error instanceof RelayerError || error instanceof NetworkError || error instanceof UserRejectedRequestError || error instanceof SignatureError || error instanceof NonceError) {
40019
+ throw error;
40020
+ }
39277
40021
  throw new BlockchainError(
39278
- `Failed to add server files and permissions: ${error instanceof Error ? error.message : "Unknown error"}`,
40022
+ `Add server files and permissions submission failed: ${error instanceof Error ? error.message : "Unknown error"}`,
39279
40023
  error
39280
40024
  );
39281
40025
  }
@@ -39304,7 +40048,11 @@ var PermissionsController = class {
39304
40048
  chain: this.context.walletClient.chain,
39305
40049
  account: this.context.walletClient.account || null
39306
40050
  });
39307
- return hash;
40051
+ return new TransactionHandle(
40052
+ this.context,
40053
+ hash,
40054
+ "revokePermission"
40055
+ );
39308
40056
  } catch (error) {
39309
40057
  throw new BlockchainError(
39310
40058
  `Failed to revoke permission: ${error instanceof Error ? error.message : "Unknown error"}`,
@@ -39312,10 +40060,128 @@ var PermissionsController = class {
39312
40060
  );
39313
40061
  }
39314
40062
  }
40063
+ /**
40064
+ * Submits a signed add permission transaction directly to the blockchain.
40065
+ *
40066
+ * @param typedData - The typed data structure for the permission addition
40067
+ * @param signature - The cryptographic signature authorizing the transaction
40068
+ * @returns Promise resolving to the transaction hash
40069
+ */
40070
+ async submitDirectAddPermissionTransaction(typedData, signature) {
40071
+ const chainId = await this.context.walletClient.getChainId();
40072
+ const DataPortabilityPermissionsAddress = getContractAddress(
40073
+ chainId,
40074
+ "DataPortabilityPermissions"
40075
+ );
40076
+ const DataPortabilityPermissionsAbi = getAbi("DataPortabilityPermissions");
40077
+ const permissionInput = {
40078
+ nonce: typedData.message.nonce,
40079
+ granteeId: typedData.message.granteeId,
40080
+ grant: typedData.message.grant,
40081
+ fileIds: typedData.message.fileIds || []
40082
+ };
40083
+ const formattedSignature = formatSignatureForContract(signature);
40084
+ const hash = await this.context.walletClient.writeContract({
40085
+ address: DataPortabilityPermissionsAddress,
40086
+ abi: DataPortabilityPermissionsAbi,
40087
+ functionName: "addPermission",
40088
+ args: [permissionInput, formattedSignature],
40089
+ account: this.context.walletClient.account || await this.getUserAddress(),
40090
+ chain: this.context.walletClient.chain || null
40091
+ });
40092
+ return hash;
40093
+ }
40094
+ /**
40095
+ * Submits a signed add server files and permissions transaction directly to the blockchain.
40096
+ *
40097
+ * @param typedData - The typed data structure for the server files and permissions addition
40098
+ * @param signature - The cryptographic signature authorizing the transaction
40099
+ * @returns Promise resolving to the transaction hash
40100
+ */
40101
+ async submitDirectAddServerFilesAndPermissionsTransaction(typedData, signature) {
40102
+ const chainId = await this.context.walletClient.getChainId();
40103
+ const DataPortabilityPermissionsAddress = getContractAddress(
40104
+ chainId,
40105
+ "DataPortabilityPermissions"
40106
+ );
40107
+ const DataPortabilityPermissionsAbi = getAbi("DataPortabilityPermissions");
40108
+ const serverFilesAndPermissionInput = {
40109
+ nonce: typedData.message.nonce,
40110
+ granteeId: typedData.message.granteeId,
40111
+ grant: typedData.message.grant,
40112
+ fileUrls: typedData.message.fileUrls,
40113
+ serverAddress: typedData.message.serverAddress,
40114
+ serverUrl: typedData.message.serverUrl,
40115
+ serverPublicKey: typedData.message.serverPublicKey,
40116
+ filePermissions: typedData.message.filePermissions
40117
+ };
40118
+ const formattedSignature = formatSignatureForContract(signature);
40119
+ const hash = await this.context.walletClient.writeContract({
40120
+ address: DataPortabilityPermissionsAddress,
40121
+ abi: DataPortabilityPermissionsAbi,
40122
+ functionName: "addServerFilesAndPermissions",
40123
+ // @ts-expect-error - Complex nested array types cause compatibility issues with viem's generated types
40124
+ args: [serverFilesAndPermissionInput, formattedSignature],
40125
+ account: this.context.walletClient.account || await this.getUserAddress(),
40126
+ chain: this.context.walletClient.chain || null
40127
+ });
40128
+ return hash;
40129
+ }
39315
40130
  };
39316
40131
 
39317
40132
  // src/controllers/data.ts
39318
- import { getContract, decodeEventLog } from "viem";
40133
+ import { getContract as getContract2 } from "viem";
40134
+
40135
+ // src/utils/blockchain/registry.ts
40136
+ import { getContract } from "viem";
40137
+ async function fetchSchemaFromChain(context, schemaId) {
40138
+ const chainId = context.walletClient.chain?.id;
40139
+ if (!chainId) {
40140
+ throw new Error("Chain ID not available");
40141
+ }
40142
+ const dataRefinerRegistryAddress = getContractAddress(
40143
+ chainId,
40144
+ "DataRefinerRegistry"
40145
+ );
40146
+ const dataRefinerRegistryAbi = getAbi("DataRefinerRegistry");
40147
+ const dataRefinerRegistry = getContract({
40148
+ address: dataRefinerRegistryAddress,
40149
+ abi: dataRefinerRegistryAbi,
40150
+ client: context.publicClient
40151
+ });
40152
+ const schemaData = await dataRefinerRegistry.read.schemas([BigInt(schemaId)]);
40153
+ if (!schemaData) {
40154
+ throw new Error(`Schema with ID ${schemaId} not found`);
40155
+ }
40156
+ const schemaObj = schemaData;
40157
+ if (!schemaObj.name || !schemaObj.dialect || !schemaObj.definitionUrl) {
40158
+ throw new Error("Incomplete schema data");
40159
+ }
40160
+ return {
40161
+ id: schemaId,
40162
+ name: schemaObj.name,
40163
+ dialect: schemaObj.dialect,
40164
+ definitionUrl: schemaObj.definitionUrl
40165
+ };
40166
+ }
40167
+ async function fetchSchemaCountFromChain(context) {
40168
+ const chainId = context.walletClient.chain?.id;
40169
+ if (!chainId) {
40170
+ throw new Error("Chain ID not available");
40171
+ }
40172
+ const dataRefinerRegistryAddress = getContractAddress(
40173
+ chainId,
40174
+ "DataRefinerRegistry"
40175
+ );
40176
+ const dataRefinerRegistryAbi = getAbi("DataRefinerRegistry");
40177
+ const dataRefinerRegistry = getContract({
40178
+ address: dataRefinerRegistryAddress,
40179
+ abi: dataRefinerRegistryAbi,
40180
+ client: context.publicClient
40181
+ });
40182
+ const count = await dataRefinerRegistry.read.schemasCount();
40183
+ return Number(count);
40184
+ }
39319
40185
 
39320
40186
  // src/utils/encryption.ts
39321
40187
  var DEFAULT_ENCRYPTION_SEED = "Please sign to retrieve your encryption key";
@@ -39397,7 +40263,11 @@ async function encryptBlobWithSignedKey(data, key, platformAdapter) {
39397
40263
  dataArray,
39398
40264
  key
39399
40265
  );
39400
- return new Blob([encrypted], {
40266
+ const encryptedArrayBuffer = encrypted.buffer.slice(
40267
+ encrypted.byteOffset,
40268
+ encrypted.byteOffset + encrypted.byteLength
40269
+ );
40270
+ return new Blob([encryptedArrayBuffer], {
39401
40271
  type: "application/octet-stream"
39402
40272
  });
39403
40273
  } catch (error) {
@@ -39426,7 +40296,11 @@ async function decryptBlobWithSignedKey(encryptedData, key, platformAdapter) {
39426
40296
  encryptedArray,
39427
40297
  key
39428
40298
  );
39429
- return new Blob([decrypted], { type: "text/plain" });
40299
+ const decryptedArrayBuffer = decrypted.buffer.slice(
40300
+ decrypted.byteOffset,
40301
+ decrypted.byteOffset + decrypted.byteLength
40302
+ );
40303
+ return new Blob([decryptedArrayBuffer], { type: "text/plain" });
39430
40304
  } catch (error) {
39431
40305
  throw new Error(`Failed to decrypt data: ${error}`);
39432
40306
  }
@@ -39443,28 +40317,16 @@ var DataController = class {
39443
40317
  filename,
39444
40318
  schemaId,
39445
40319
  permissions = [],
39446
- encrypt: encrypt2 = true,
40320
+ encrypt = true,
39447
40321
  providerName,
39448
40322
  owner
39449
40323
  } = params;
39450
40324
  try {
39451
- let blob;
39452
- if (content instanceof Blob) {
39453
- blob = content;
39454
- } else if (typeof content === "string") {
39455
- blob = new Blob([content], { type: "text/plain" });
39456
- } else if (content instanceof Buffer) {
39457
- blob = new Blob([content], { type: "application/octet-stream" });
39458
- } else {
39459
- blob = new Blob([JSON.stringify(content)], {
39460
- type: "application/json"
39461
- });
39462
- }
39463
40325
  let isValid = true;
39464
40326
  let validationErrors = [];
39465
40327
  if (schemaId !== void 0) {
39466
40328
  try {
39467
- const schema = await this.getSchema(schemaId);
40329
+ const schema = await fetchSchemaFromChain(this.context, schemaId);
39468
40330
  const response = await fetch(schema.definitionUrl);
39469
40331
  if (!response.ok) {
39470
40332
  throw new Error(
@@ -39496,37 +40358,15 @@ var DataController = class {
39496
40358
  ];
39497
40359
  }
39498
40360
  }
39499
- let finalBlob = blob;
39500
- if (encrypt2) {
39501
- const encryptionKey = await generateEncryptionKey(
39502
- this.context.walletClient,
39503
- this.context.platform,
39504
- DEFAULT_ENCRYPTION_SEED
39505
- );
39506
- finalBlob = await encryptBlobWithSignedKey(
39507
- blob,
39508
- encryptionKey,
39509
- this.context.platform
39510
- );
39511
- }
39512
- if (!this.context.storageManager) {
39513
- if (this.context.validateStorageRequired) {
39514
- this.context.validateStorageRequired();
39515
- throw new Error("Storage validation failed");
39516
- } else {
39517
- throw new Error(
39518
- "Storage manager not configured. Please provide storage providers in VanaConfig."
39519
- );
39520
- }
39521
- }
39522
- const uploadResult = await this.context.storageManager.upload(
39523
- finalBlob,
40361
+ const uploadResult = await this.uploadToStorage(
40362
+ content,
39524
40363
  filename,
40364
+ encrypt,
39525
40365
  providerName
39526
40366
  );
39527
40367
  const userAddress = owner || await this.getUserAddress();
39528
40368
  let encryptedPermissions = [];
39529
- if (permissions.length > 0) {
40369
+ if (permissions.length > 0 && encrypt) {
39530
40370
  const userEncryptionKey = await generateEncryptionKey(
39531
40371
  this.context.walletClient,
39532
40372
  this.context.platform,
@@ -39767,8 +40607,8 @@ var DataController = class {
39767
40607
  */
39768
40608
  async getUserFiles(params) {
39769
40609
  const { owner, subgraphUrl } = params;
39770
- const graphqlEndpoint = subgraphUrl || this.context.subgraphUrl;
39771
- if (!graphqlEndpoint) {
40610
+ const endpoint = subgraphUrl || this.context.subgraphUrl;
40611
+ if (!endpoint) {
39772
40612
  throw new Error(
39773
40613
  "subgraphUrl is required. Please provide a valid subgraph endpoint or configure it in Vana constructor."
39774
40614
  );
@@ -39792,7 +40632,7 @@ var DataController = class {
39792
40632
  }
39793
40633
  }
39794
40634
  `;
39795
- const response = await fetch(graphqlEndpoint, {
40635
+ const response = await fetch(endpoint, {
39796
40636
  method: "POST",
39797
40637
  headers: {
39798
40638
  "Content-Type": "application/json"
@@ -39850,28 +40690,45 @@ var DataController = class {
39850
40690
  }
39851
40691
  }
39852
40692
  /**
39853
- * Retrieves a list of permissions granted by a user using the new subgraph entities.
40693
+ * Retrieves a list of permissions granted by a user.
39854
40694
  *
39855
- * This method queries the Vana subgraph to find permissions directly granted by the user
39856
- * using the new Permission entity. It efficiently handles millions of permissions by:
39857
- * 1. Querying the subgraph for user's directly granted permissions
39858
- * 2. Returning complete permission information from subgraph
39859
- * 3. No need for additional contract calls as all data comes from subgraph
40695
+ * This method supports automatic fallback between subgraph and RPC modes:
40696
+ * - If subgraph URL is available, tries subgraph query first
40697
+ * - Falls back to direct contract queries via RPC if subgraph fails
40698
+ * - RPC mode uses gasAwareMulticall for efficient batch queries
39860
40699
  *
39861
40700
  * @param params - Object containing the user address and optional subgraph URL
39862
40701
  * @param params.user - The wallet address of the user to query permissions for
39863
40702
  * @param params.subgraphUrl - Optional subgraph URL to override the default
39864
40703
  * @returns Promise resolving to an array of permission objects
39865
- * @throws Error if subgraph is unavailable or returns invalid data
40704
+ * @throws Error if both subgraph and RPC queries fail
39866
40705
  */
39867
40706
  async getUserPermissions(params) {
39868
40707
  const { user, subgraphUrl } = params;
39869
- const graphqlEndpoint = subgraphUrl || this.context.subgraphUrl;
39870
- if (!graphqlEndpoint) {
39871
- throw new Error(
39872
- "subgraphUrl is required. Please provide a valid subgraph endpoint or configure it in Vana constructor."
39873
- );
40708
+ const endpoint = subgraphUrl || this.context.subgraphUrl;
40709
+ if (endpoint) {
40710
+ try {
40711
+ const permissions = await this._getUserPermissionsViaSubgraph({
40712
+ user,
40713
+ subgraphUrl: endpoint
40714
+ });
40715
+ return permissions;
40716
+ } catch (error) {
40717
+ console.warn("Subgraph query failed, falling back to RPC:", error);
40718
+ }
39874
40719
  }
40720
+ return await this._getUserPermissionsViaRpc({ user });
40721
+ }
40722
+ /**
40723
+ * Internal method: Query user permissions via subgraph
40724
+ *
40725
+ * @param params - Query parameters object
40726
+ * @param params.user - The user address to query permissions for
40727
+ * @param params.subgraphUrl - The subgraph URL endpoint to query
40728
+ * @returns Promise resolving to an array of permission objects
40729
+ */
40730
+ async _getUserPermissionsViaSubgraph(params) {
40731
+ const { user, subgraphUrl } = params;
39875
40732
  try {
39876
40733
  const query = `
39877
40734
  query GetUserPermissions($userId: ID!) {
@@ -39892,7 +40749,7 @@ var DataController = class {
39892
40749
  }
39893
40750
  }
39894
40751
  `;
39895
- const response = await fetch(graphqlEndpoint, {
40752
+ const response = await fetch(subgraphUrl, {
39896
40753
  method: "POST",
39897
40754
  headers: {
39898
40755
  "Content-Type": "application/json"
@@ -39912,15 +40769,14 @@ var DataController = class {
39912
40769
  const result = await response.json();
39913
40770
  if (result.errors) {
39914
40771
  throw new Error(
39915
- `Subgraph errors: ${result.errors.map((e) => e.message).join(", ")}`
40772
+ `Subgraph query errors: ${result.errors.map((e) => e.message).join(", ")}`
39916
40773
  );
39917
40774
  }
39918
40775
  const userData = result.data?.user;
39919
40776
  if (!userData || !userData.permissions?.length) {
39920
- console.warn("No permissions found for user:", user);
39921
40777
  return [];
39922
40778
  }
39923
- const permissions = userData.permissions.map((permission) => ({
40779
+ return userData.permissions.map((permission) => ({
39924
40780
  id: permission.id,
39925
40781
  grant: permission.grant,
39926
40782
  nonce: BigInt(permission.nonce),
@@ -39930,131 +40786,158 @@ var DataController = class {
39930
40786
  transactionHash: permission.transactionHash,
39931
40787
  user: permission.user.id
39932
40788
  })).sort((a, b) => Number(b.addedAtTimestamp - a.addedAtTimestamp));
40789
+ } catch (error) {
40790
+ console.error("Failed to query user permissions from subgraph:", error);
40791
+ throw error;
40792
+ }
40793
+ }
40794
+ /**
40795
+ * Internal method: Query user permissions via direct RPC
40796
+ *
40797
+ * @param params - Query parameters object
40798
+ * @param params.user - The user address to query permissions for
40799
+ * @returns Promise resolving to an array of permission objects
40800
+ */
40801
+ async _getUserPermissionsViaRpc(params) {
40802
+ const { user } = params;
40803
+ try {
40804
+ const chainId = this.context.walletClient.chain?.id;
40805
+ if (!chainId) {
40806
+ throw new Error("Chain ID not available");
40807
+ }
40808
+ const permissionsAddress = getContractAddress(
40809
+ chainId,
40810
+ "DataPortabilityPermissions"
40811
+ );
40812
+ const permissionsAbi = getAbi("DataPortabilityPermissions");
40813
+ const totalCount = await this.context.publicClient.readContract({
40814
+ address: permissionsAddress,
40815
+ abi: permissionsAbi,
40816
+ functionName: "userPermissionIdsLength",
40817
+ args: [user]
40818
+ });
40819
+ const total = Number(totalCount);
40820
+ if (total === 0) {
40821
+ return [];
40822
+ }
40823
+ const permissionIdCalls = [];
40824
+ for (let i = 0; i < total; i++) {
40825
+ permissionIdCalls.push({
40826
+ address: permissionsAddress,
40827
+ abi: permissionsAbi,
40828
+ functionName: "userPermissionIdsAt",
40829
+ args: [user, BigInt(i)]
40830
+ });
40831
+ }
40832
+ const permissionIdResults = await gasAwareMulticall(this.context.publicClient, {
40833
+ contracts: permissionIdCalls
40834
+ });
40835
+ const permissionIds = permissionIdResults.map((result) => result).filter((id) => id && id > 0n);
40836
+ const permissionInfoCalls = permissionIds.map(
40837
+ (permissionId) => ({
40838
+ address: permissionsAddress,
40839
+ abi: permissionsAbi,
40840
+ functionName: "permissions",
40841
+ args: [permissionId]
40842
+ })
40843
+ );
40844
+ const permissionInfoResults = await gasAwareMulticall(this.context.publicClient, {
40845
+ contracts: permissionInfoCalls,
40846
+ allowFailure: true
40847
+ });
40848
+ const permissions = permissionInfoResults.map((result, index) => {
40849
+ const permissionId = permissionIds[index];
40850
+ if (result.status === "success" && result.result) {
40851
+ const permissionInfo = result.result;
40852
+ return {
40853
+ id: permissionId.toString(),
40854
+ grant: permissionInfo.grant,
40855
+ nonce: permissionInfo.nonce,
40856
+ signature: "",
40857
+ // Not available from RPC, will be empty
40858
+ addedAtBlock: permissionInfo.startBlock,
40859
+ addedAtTimestamp: BigInt(0),
40860
+ // Not available from RPC
40861
+ transactionHash: "0x0000000000000000000000000000000000000000",
40862
+ // Not available from RPC
40863
+ user
40864
+ };
40865
+ } else {
40866
+ return {
40867
+ id: permissionId.toString(),
40868
+ grant: "",
40869
+ nonce: BigInt(0),
40870
+ signature: "",
40871
+ addedAtBlock: BigInt(0),
40872
+ addedAtTimestamp: BigInt(0),
40873
+ transactionHash: "0x0000000000000000000000000000000000000000",
40874
+ user
40875
+ };
40876
+ }
40877
+ }).filter((permission) => permission.grant !== "");
39933
40878
  return permissions;
39934
40879
  } catch (error) {
39935
- console.error("Failed to fetch user permissions from subgraph:", error);
39936
40880
  throw new Error(
39937
- `Failed to fetch user permissions from subgraph: ${error instanceof Error ? error.message : "Unknown error"}`
40881
+ `RPC query failed: ${error instanceof Error ? error.message : "Unknown error"}`
39938
40882
  );
39939
40883
  }
39940
40884
  }
39941
40885
  /**
39942
- * Retrieves a list of trusted servers for a user using the new subgraph entities.
40886
+ * Retrieves a list of trusted servers for a user.
39943
40887
  *
39944
- * This method queries the Vana subgraph to find trusted servers directly associated with the user
39945
- * with support for both subgraph and direct RPC queries.
40888
+ * This method supports automatic fallback between subgraph and RPC modes:
40889
+ * - If subgraph URL is available, tries subgraph query first for fast results
40890
+ * - Falls back to direct contract queries via RPC if subgraph fails
40891
+ * - RPC mode uses gasAwareMulticall for efficient batch queries
39946
40892
  *
39947
- * This method supports multiple query modes:
39948
- * - 'subgraph': Fast query via subgraph (requires subgraphUrl)
39949
- * - 'rpc': Direct contract queries (slower but no external dependencies)
39950
- * - 'auto': Try subgraph first, fallback to RPC if unavailable
39951
- *
39952
- * @param params - Query parameters including user address and mode selection
39953
- * @returns Promise resolving to trusted servers with metadata about the query
39954
- * @throws Error if query fails in both modes (when using 'auto')
40893
+ * @param params - Query parameters including user address and optional pagination
40894
+ * @param params.user - The wallet address of the user to query trusted servers for
40895
+ * @param params.subgraphUrl - Optional subgraph URL to override the default
40896
+ * @param params.limit - Maximum number of results to return (default: 50)
40897
+ * @param params.offset - Number of results to skip for pagination (default: 0)
40898
+ * @returns Promise resolving to an array of trusted server objects
40899
+ * @throws Error if both subgraph and RPC queries fail
39955
40900
  * @example
39956
40901
  * ```typescript
39957
- * // Use subgraph for fast queries
39958
- * const result = await vana.data.getUserTrustedServers({
39959
- * user: '0x...',
39960
- * mode: 'subgraph',
39961
- * subgraphUrl: 'https://...'
40902
+ * // Basic usage with automatic fallback
40903
+ * const servers = await vana.data.getUserTrustedServers({
40904
+ * user: '0x...'
39962
40905
  * });
39963
40906
  *
39964
- * // Use direct RPC (no external dependencies)
39965
- * const result = await vana.data.getUserTrustedServers({
40907
+ * // With pagination
40908
+ * const servers = await vana.data.getUserTrustedServers({
39966
40909
  * user: '0x...',
39967
- * mode: 'rpc',
39968
- * limit: 10
40910
+ * limit: 10,
40911
+ * offset: 20
39969
40912
  * });
39970
40913
  *
39971
- * // Auto-fallback mode
39972
- * const result = await vana.data.getUserTrustedServers({
40914
+ * // With custom subgraph URL
40915
+ * const servers = await vana.data.getUserTrustedServers({
39973
40916
  * user: '0x...',
39974
- * mode: 'auto' // tries subgraph first, falls back to RPC
40917
+ * subgraphUrl: 'https://custom-subgraph.com/graphql'
39975
40918
  * });
39976
40919
  * ```
39977
40920
  */
39978
40921
  async getUserTrustedServers(params) {
39979
- const { user, mode = "auto", limit = 50, offset = 0 } = params;
39980
- const warnings = [];
39981
- let trySubgraph = false;
39982
- let tryRpc = false;
39983
- switch (mode) {
39984
- case "subgraph":
39985
- trySubgraph = true;
39986
- break;
39987
- case "rpc":
39988
- tryRpc = true;
39989
- break;
39990
- case "auto":
39991
- trySubgraph = true;
39992
- tryRpc = true;
39993
- break;
39994
- }
39995
- if (trySubgraph) {
39996
- const subgraphUrl = params.subgraphUrl || this.context.subgraphUrl;
39997
- if (!subgraphUrl) {
39998
- if (mode === "subgraph") {
39999
- throw new Error(
40000
- "subgraphUrl is required for subgraph mode. Please provide a valid subgraph endpoint or configure it in Vana constructor."
40001
- );
40002
- }
40003
- warnings.push(
40004
- "Subgraph mode not available for trusted servers - using direct contract calls"
40005
- );
40006
- } else {
40007
- try {
40008
- const servers = await this._getUserTrustedServersViaSubgraph({
40009
- user,
40010
- subgraphUrl
40011
- });
40012
- const paginatedServers = limit ? servers.slice(offset, offset + limit) : servers;
40013
- return {
40014
- servers: paginatedServers,
40015
- usedMode: "subgraph",
40016
- total: servers.length,
40017
- hasMore: limit ? offset + limit < servers.length : false,
40018
- warnings: warnings.length > 0 ? warnings : void 0
40019
- };
40020
- } catch (error) {
40021
- if (mode === "subgraph") {
40022
- throw error;
40023
- }
40024
- warnings.push(
40025
- `Subgraph query failed: ${error instanceof Error ? error.message : "Unknown error"}`
40026
- );
40027
- console.warn(
40028
- "Subgraph query failed, falling back to RPC mode:",
40029
- error
40030
- );
40031
- }
40032
- }
40033
- }
40034
- if (tryRpc) {
40922
+ const { user, limit = 50, offset = 0 } = params;
40923
+ const subgraphUrl = params.subgraphUrl || this.context.subgraphUrl;
40924
+ if (subgraphUrl) {
40035
40925
  try {
40036
- const rpcResult = await this._getUserTrustedServersViaRpc({
40926
+ const servers = await this._getUserTrustedServersViaSubgraph({
40037
40927
  user,
40038
- limit,
40039
- offset
40928
+ subgraphUrl
40040
40929
  });
40041
- return {
40042
- servers: rpcResult.servers,
40043
- usedMode: "rpc",
40044
- total: rpcResult.total,
40045
- hasMore: rpcResult.hasMore,
40046
- warnings: warnings.length > 0 ? warnings : void 0
40047
- };
40930
+ return limit ? servers.slice(offset, offset + limit) : servers;
40048
40931
  } catch (error) {
40049
- if (mode === "rpc") {
40050
- throw error;
40051
- }
40052
- throw new Error(
40053
- `Both query methods failed. Subgraph: ${warnings[0] || "Unknown error"}. RPC: ${error instanceof Error ? error.message : "Unknown error"}`
40054
- );
40932
+ console.warn("Subgraph query failed, falling back to RPC:", error);
40055
40933
  }
40056
40934
  }
40057
- throw new Error("Invalid query mode specified");
40935
+ const rpcResult = await this._getUserTrustedServersViaRpc({
40936
+ user,
40937
+ limit,
40938
+ offset
40939
+ });
40940
+ return rpcResult.servers;
40058
40941
  }
40059
40942
  /**
40060
40943
  * Internal method: Query trusted servers via subgraph
@@ -40170,35 +41053,44 @@ var DataController = class {
40170
41053
  };
40171
41054
  }
40172
41055
  const endIndex = Math.min(offset + limit, total);
40173
- const serverIdPromises = [];
41056
+ const serverIdCalls = [];
40174
41057
  for (let i = offset; i < endIndex; i++) {
40175
- const promise = this.context.publicClient.readContract({
41058
+ serverIdCalls.push({
40176
41059
  address: DataPortabilityServersAddress,
40177
41060
  abi: DataPortabilityServersAbi,
40178
41061
  functionName: "userServerIdsAt",
40179
41062
  args: [user, BigInt(i)]
40180
41063
  });
40181
- serverIdPromises.push(promise);
40182
41064
  }
40183
- const serverIds = await Promise.all(serverIdPromises);
40184
- const serverInfoPromises = serverIds.map(async (serverId, index) => {
40185
- try {
40186
- const serverInfo = await this.context.publicClient.readContract({
40187
- address: DataPortabilityServersAddress,
40188
- abi: DataPortabilityServersAbi,
40189
- functionName: "servers",
40190
- args: [serverId]
40191
- });
41065
+ const serverIdResults = await gasAwareMulticall(this.context.publicClient, {
41066
+ contracts: serverIdCalls
41067
+ });
41068
+ const serverIds = serverIdResults.map((result) => result).filter((id) => id && id > 0n);
41069
+ const serverInfoCalls = serverIds.map(
41070
+ (serverId) => ({
41071
+ address: DataPortabilityServersAddress,
41072
+ abi: DataPortabilityServersAbi,
41073
+ functionName: "servers",
41074
+ args: [serverId]
41075
+ })
41076
+ );
41077
+ const serverInfoResults = await gasAwareMulticall(this.context.publicClient, {
41078
+ contracts: serverInfoCalls,
41079
+ allowFailure: true
41080
+ });
41081
+ const servers = serverInfoResults.map((result, index) => {
41082
+ const serverId = serverIds[index];
41083
+ if (result.status === "success" && result.result) {
41084
+ const serverInfo = result.result;
40192
41085
  return {
40193
41086
  id: `${user.toLowerCase()}-${serverId.toString()}`,
40194
41087
  serverAddress: serverInfo.serverAddress,
40195
41088
  serverUrl: serverInfo.url,
40196
41089
  trustedAt: BigInt(Date.now()),
40197
- // RPC mode doesn't have timestamp, use current time
40198
41090
  user,
40199
41091
  trustIndex: offset + index
40200
41092
  };
40201
- } catch {
41093
+ } else {
40202
41094
  return {
40203
41095
  id: `${user.toLowerCase()}-${serverId.toString()}`,
40204
41096
  serverAddress: "0x0000000000000000000000000000000000000000",
@@ -40209,7 +41101,6 @@ var DataController = class {
40209
41101
  };
40210
41102
  }
40211
41103
  });
40212
- const servers = await Promise.all(serverInfoPromises);
40213
41104
  return {
40214
41105
  servers,
40215
41106
  total,
@@ -40244,7 +41135,7 @@ var DataController = class {
40244
41135
  }
40245
41136
  const dataRegistryAddress = getContractAddress(chainId, "DataRegistry");
40246
41137
  const dataRegistryAbi = getAbi("DataRegistry");
40247
- const dataRegistry = getContract({
41138
+ const dataRegistry = getContract2({
40248
41139
  address: dataRegistryAddress,
40249
41140
  abi: dataRegistryAbi,
40250
41141
  client: this.context.walletClient
@@ -40295,7 +41186,7 @@ var DataController = class {
40295
41186
  }
40296
41187
  const dataRegistryAddress = getContractAddress(chainId, "DataRegistry");
40297
41188
  const dataRegistryAbi = getAbi("DataRegistry");
40298
- const dataRegistry = getContract({
41189
+ const dataRegistry = getContract2({
40299
41190
  address: dataRegistryAddress,
40300
41191
  abi: dataRegistryAbi,
40301
41192
  client: this.context.walletClient
@@ -40333,214 +41224,28 @@ var DataController = class {
40333
41224
  );
40334
41225
  }
40335
41226
  }
40336
- /**
40337
- * Uploads an encrypted file to storage and registers it on the blockchain.
40338
- *
40339
- * @deprecated Since v2.0.0 - Use vana.data.upload() instead for the high-level API with automatic encryption
40340
- *
40341
- * Migration guide:
40342
- * ```typescript
40343
- * // Old way (deprecated):
40344
- * const encrypted = await encryptBlob(data, key);
40345
- * const result = await vana.data.uploadEncryptedFile(encrypted, filename);
40346
- *
40347
- * // New way:
40348
- * const result = await vana.data.upload({
40349
- * content: data,
40350
- * filename: filename,
40351
- * encrypt: true // Handles encryption automatically
40352
- * });
40353
- * ```
40354
- * @param encryptedFile - The encrypted file blob to upload
40355
- * @param filename - Optional filename for the upload
40356
- * @param providerName - Optional storage provider to use
40357
- * @returns Promise resolving to upload result with file ID and storage URL
40358
- *
40359
- * This method handles the complete flow of:
40360
- * 1. Uploading the encrypted file to the specified storage provider
40361
- * 2. Registering the file URL on the DataRegistry contract via relayer
40362
- * 3. Returning the assigned file ID and storage URL
40363
- */
40364
- async uploadEncryptedFile(encryptedFile, filename, providerName) {
40365
- try {
40366
- if (!this.context.storageManager) {
40367
- throw new Error(
40368
- "Storage manager not configured. Please provide storage providers in VanaConfig."
40369
- );
40370
- }
40371
- const uploadResult = await this.context.storageManager.upload(
40372
- encryptedFile,
40373
- filename,
40374
- providerName
40375
- );
40376
- const userAddress = await this.getUserAddress();
40377
- if (this.context.relayerCallbacks?.submitFileAddition) {
40378
- const result = await this.context.relayerCallbacks.submitFileAddition(
40379
- uploadResult.url,
40380
- userAddress
40381
- );
40382
- return {
40383
- fileId: result.fileId,
40384
- url: uploadResult.url,
40385
- size: uploadResult.size,
40386
- transactionHash: result.transactionHash
40387
- };
40388
- } else {
40389
- const chainId = this.context.walletClient.chain?.id;
40390
- if (!chainId) {
40391
- throw new Error("Chain ID not available");
40392
- }
40393
- const dataRegistryAddress = getContractAddress(chainId, "DataRegistry");
40394
- const dataRegistryAbi = getAbi("DataRegistry");
40395
- const txHash = await this.context.walletClient.writeContract({
40396
- address: dataRegistryAddress,
40397
- abi: dataRegistryAbi,
40398
- functionName: "addFile",
40399
- args: [uploadResult.url],
40400
- account: this.context.walletClient.account || userAddress,
40401
- chain: this.context.walletClient.chain || null
40402
- });
40403
- const receipt = await this.context.publicClient.waitForTransactionReceipt({
40404
- hash: txHash,
40405
- timeout: 3e4
40406
- // 30 seconds timeout
40407
- });
40408
- let fileId = 0;
40409
- for (const log of receipt.logs) {
40410
- try {
40411
- const decoded = decodeEventLog({
40412
- abi: dataRegistryAbi,
40413
- data: log.data,
40414
- topics: log.topics
40415
- });
40416
- if (decoded.eventName === "FileAdded") {
40417
- fileId = Number(decoded.args.fileId);
40418
- break;
40419
- }
40420
- } catch {
40421
- continue;
40422
- }
40423
- }
40424
- return {
40425
- fileId,
40426
- url: uploadResult.url,
40427
- size: uploadResult.size,
40428
- transactionHash: txHash
40429
- };
40430
- }
40431
- } catch (error) {
40432
- console.error("Failed to upload encrypted file:", error);
40433
- throw new Error(
40434
- `Upload failed: ${error instanceof Error ? error.message : "Unknown error"}`
40435
- );
40436
- }
40437
- }
40438
- /**
40439
- * Uploads an encrypted file to storage and registers it on the blockchain with a schema.
40440
- *
40441
- * @deprecated Since v2.0.0 - Use vana.data.upload() instead for the high-level API with automatic encryption and schema validation
40442
- *
40443
- * Migration guide:
40444
- * ```typescript
40445
- * // Old way (deprecated):
40446
- * const encrypted = await encryptBlob(data, key);
40447
- * const result = await vana.data.uploadEncryptedFileWithSchema(encrypted, schemaId, filename);
40448
- *
40449
- * // New way:
40450
- * const result = await vana.data.upload({
40451
- * content: data,
40452
- * filename: filename,
40453
- * schemaId: schemaId, // Automatic validation
40454
- * encrypt: true
40455
- * });
40456
- * ```
40457
- * @param encryptedFile - The encrypted file blob to upload
40458
- * @param schemaId - The schema ID to associate with the file
40459
- * @param filename - Optional filename for the upload
40460
- * @param providerName - Optional storage provider to use
40461
- * @returns Promise resolving to upload result with file ID and storage URL
40462
- *
40463
- * This method handles the complete flow of:
40464
- * 1. Uploading the encrypted file to the specified storage provider
40465
- * 2. Registering the file URL on the DataRegistry contract with a schema ID
40466
- * 3. Returning the assigned file ID and storage URL
40467
- */
40468
- async uploadEncryptedFileWithSchema(encryptedFile, schemaId, filename, providerName) {
40469
- try {
40470
- if (!this.context.storageManager) {
40471
- throw new Error(
40472
- "Storage manager not configured. Please provide storage providers in VanaConfig."
40473
- );
40474
- }
40475
- const uploadResult = await this.context.storageManager.upload(
40476
- encryptedFile,
40477
- filename,
40478
- providerName
40479
- );
40480
- const userAddress = await this.getUserAddress();
40481
- if (this.context.relayerCallbacks?.submitFileAddition) {
40482
- throw new Error(
40483
- "Relayer does not yet support uploading files with schema. Please use direct transaction mode."
40484
- );
40485
- } else {
40486
- const chainId = this.context.walletClient.chain?.id;
40487
- if (!chainId) {
40488
- throw new Error("Chain ID not available");
40489
- }
40490
- const dataRegistryAddress = getContractAddress(chainId, "DataRegistry");
40491
- const dataRegistryAbi = getAbi("DataRegistry");
40492
- const txHash = await this.context.walletClient.writeContract({
40493
- address: dataRegistryAddress,
40494
- abi: dataRegistryAbi,
40495
- functionName: "addFileWithSchema",
40496
- args: [uploadResult.url, BigInt(schemaId)],
40497
- account: this.context.walletClient.account || userAddress,
40498
- chain: this.context.walletClient.chain || null
40499
- });
40500
- const receipt = await this.context.publicClient.waitForTransactionReceipt({
40501
- hash: txHash,
40502
- timeout: 3e4
40503
- // 30 seconds timeout
40504
- });
40505
- let fileId = 0;
40506
- for (const log of receipt.logs) {
40507
- try {
40508
- const decoded = decodeEventLog({
40509
- abi: dataRegistryAbi,
40510
- data: log.data,
40511
- topics: log.topics
40512
- });
40513
- if (decoded.eventName === "FileAdded") {
40514
- fileId = Number(decoded.args.fileId);
40515
- break;
40516
- }
40517
- } catch {
40518
- continue;
40519
- }
40520
- }
40521
- return {
40522
- fileId,
40523
- url: uploadResult.url,
40524
- size: uploadResult.size,
40525
- transactionHash: txHash
40526
- };
40527
- }
40528
- } catch (error) {
40529
- console.error("Failed to upload encrypted file with schema:", error);
40530
- throw new Error(
40531
- `Upload failed: ${error instanceof Error ? error.message : "Unknown error"}`
40532
- );
40533
- }
40534
- }
40535
41227
  /**
40536
41228
  * Registers a file URL directly on the blockchain with a schema ID.
40537
41229
  *
40538
- * @param url - The URL of the file to register
41230
+ * @remarks
41231
+ * This method registers an existing file URL on the DataRegistry contract
41232
+ * with a schema ID, without uploading any data. Useful when you have already
41233
+ * uploaded content to storage and just need to register it on-chain.
41234
+ *
41235
+ * @param url - The URL of the file to register (IPFS or HTTP/HTTPS)
40539
41236
  * @param schemaId - The schema ID to associate with the file
40540
41237
  * @returns Promise resolving to the file ID and transaction hash
40541
- *
40542
- * This method registers an existing file URL on the DataRegistry
40543
- * contract with a schema ID, without uploading any data.
41238
+ * @throws {Error} When chain ID is not available - "Chain ID not available"
41239
+ * @throws {Error} When wallet address is unavailable - "No addresses available"
41240
+ * @throws {Error} When transaction fails - "Failed to register file with schema"
41241
+ * @example
41242
+ * ```typescript
41243
+ * const { fileId, transactionHash } = await vana.data.registerFileWithSchema(
41244
+ * "ipfs://QmXxx...",
41245
+ * 1
41246
+ * );
41247
+ * console.log(`File ${fileId} registered with schema in tx ${transactionHash}`);
41248
+ * ```
40544
41249
  */
40545
41250
  async registerFileWithSchema(url, schemaId) {
40546
41251
  try {
@@ -40559,30 +41264,14 @@ var DataController = class {
40559
41264
  account: this.context.walletClient.account || userAddress,
40560
41265
  chain: this.context.walletClient.chain || null
40561
41266
  });
40562
- const receipt = await this.context.publicClient.waitForTransactionReceipt(
40563
- {
40564
- hash: txHash,
40565
- timeout: 3e4
40566
- }
41267
+ const txHandle = new TransactionHandle(
41268
+ this.context,
41269
+ txHash,
41270
+ "addFileWithSchema"
40567
41271
  );
40568
- let fileId = 0;
40569
- for (const log of receipt.logs) {
40570
- try {
40571
- const decoded = decodeEventLog({
40572
- abi: dataRegistryAbi,
40573
- data: log.data,
40574
- topics: log.topics
40575
- });
40576
- if (decoded.eventName === "FileAdded") {
40577
- fileId = Number(decoded.args.fileId);
40578
- break;
40579
- }
40580
- } catch {
40581
- continue;
40582
- }
40583
- }
41272
+ const result = await txHandle.waitForEvents();
40584
41273
  return {
40585
- fileId,
41274
+ fileId: Number(result.fileId),
40586
41275
  transactionHash: txHash
40587
41276
  };
40588
41277
  } catch (error) {
@@ -40637,31 +41326,14 @@ var DataController = class {
40637
41326
  account: this.context.walletClient.account || ownerAddress,
40638
41327
  chain: this.context.walletClient.chain || null
40639
41328
  });
40640
- const receipt = await this.context.publicClient.waitForTransactionReceipt(
40641
- {
40642
- hash: txHash,
40643
- timeout: 3e4
40644
- // 30 seconds timeout
40645
- }
41329
+ const txHandle = new TransactionHandle(
41330
+ this.context,
41331
+ txHash,
41332
+ "addFileWithPermissions"
40646
41333
  );
40647
- let fileId = 0;
40648
- for (const log of receipt.logs) {
40649
- try {
40650
- const decoded = decodeEventLog({
40651
- abi: dataRegistryAbi,
40652
- data: log.data,
40653
- topics: log.topics
40654
- });
40655
- if (decoded.eventName === "FileAdded") {
40656
- fileId = Number(decoded.args.fileId);
40657
- break;
40658
- }
40659
- } catch {
40660
- continue;
40661
- }
40662
- }
41334
+ const result = await txHandle.waitForEvents();
40663
41335
  return {
40664
- fileId,
41336
+ fileId: Number(result.fileId),
40665
41337
  transactionHash: txHash
40666
41338
  };
40667
41339
  } catch (error) {
@@ -40701,31 +41373,14 @@ var DataController = class {
40701
41373
  account: this.context.walletClient.account || ownerAddress,
40702
41374
  chain: this.context.walletClient.chain || null
40703
41375
  });
40704
- const receipt = await this.context.publicClient.waitForTransactionReceipt(
40705
- {
40706
- hash: txHash,
40707
- timeout: 3e4
40708
- // 30 seconds timeout
40709
- }
41376
+ const txHandle = new TransactionHandle(
41377
+ this.context,
41378
+ txHash,
41379
+ "addFileWithPermissionsAndSchema"
40710
41380
  );
40711
- let fileId = 0;
40712
- for (const log of receipt.logs) {
40713
- try {
40714
- const decoded = decodeEventLog({
40715
- abi: dataRegistryAbi,
40716
- data: log.data,
40717
- topics: log.topics
40718
- });
40719
- if (decoded.eventName === "FileAdded") {
40720
- fileId = Number(decoded.args.fileId);
40721
- break;
40722
- }
40723
- } catch {
40724
- continue;
40725
- }
40726
- }
41381
+ const result = await txHandle.waitForEvents();
40727
41382
  return {
40728
- fileId,
41383
+ fileId: Number(result.fileId),
40729
41384
  transactionHash: txHash
40730
41385
  };
40731
41386
  } catch (error) {
@@ -40736,179 +41391,32 @@ var DataController = class {
40736
41391
  }
40737
41392
  }
40738
41393
  /**
40739
- * Adds a new schema to the DataRefinerRegistry.
40740
- *
40741
- * @deprecated Since v2.0.0 - Use vana.schemas.create() instead for the high-level API with automatic IPFS upload
41394
+ * Adds a new refiner to the DataRefinerRegistry.
40742
41395
  *
40743
- * Migration guide:
41396
+ * @remarks
41397
+ * Refiners are data processing templates that define how raw data should be
41398
+ * transformed into structured formats. Each refiner is associated with a DLP
41399
+ * (Data Liquidity Pool), has a specific schema for output, and includes
41400
+ * instructions for the refinement process.
41401
+ *
41402
+ * @param params - Refiner configuration parameters
41403
+ * @param params.dlpId - The Data Liquidity Pool ID this refiner belongs to
41404
+ * @param params.name - Human-readable name for the refiner
41405
+ * @param params.schemaId - Schema ID that defines the output format
41406
+ * @param params.refinementInstructionUrl - URL containing processing instructions
41407
+ * @returns Promise resolving to the new refiner ID and transaction hash
41408
+ * @throws {Error} When chain ID is not available - "Chain ID not available"
41409
+ * @throws {Error} When transaction fails - "Failed to add refiner: {error}"
41410
+ * @example
40744
41411
  * ```typescript
40745
- * // Old way (deprecated):
40746
- * const result = await vana.data.addSchema({
40747
- * name: "UserProfile",
40748
- * type: "JSON",
40749
- * definitionUrl: "ipfs://..."
41412
+ * const result = await vana.data.addRefiner({
41413
+ * dlpId: 1,
41414
+ * name: "Social Media Sentiment Analyzer",
41415
+ * schemaId: 42,
41416
+ * refinementInstructionUrl: "ipfs://QmXxx..."
40750
41417
  * });
40751
- *
40752
- * // New way:
40753
- * const result = await vana.schemas.create({
40754
- * name: "UserProfile",
40755
- * type: "JSON",
40756
- * definition: schemaObject // Automatically uploads to IPFS
40757
- * });
40758
- * ```
40759
- * @param params - Schema parameters including name, type, and definition URL
40760
- * @returns Promise resolving to the new schema ID and transaction hash
40761
- */
40762
- async addSchema(params) {
40763
- try {
40764
- const chainId = this.context.walletClient.chain?.id;
40765
- if (!chainId) {
40766
- throw new Error("Chain ID not available");
40767
- }
40768
- const dataRefinerRegistryAddress = getContractAddress(
40769
- chainId,
40770
- "DataRefinerRegistry"
40771
- );
40772
- const dataRefinerRegistryAbi = getAbi("DataRefinerRegistry");
40773
- const txHash = await this.context.walletClient.writeContract({
40774
- address: dataRefinerRegistryAddress,
40775
- abi: dataRefinerRegistryAbi,
40776
- functionName: "addSchema",
40777
- args: [params.name, params.type, params.definitionUrl],
40778
- account: this.context.walletClient.account || await this.getUserAddress(),
40779
- chain: this.context.walletClient.chain || null
40780
- });
40781
- const receipt = await this.context.publicClient.waitForTransactionReceipt(
40782
- {
40783
- hash: txHash,
40784
- timeout: 3e4
40785
- }
40786
- );
40787
- let schemaId = 0;
40788
- for (const log of receipt.logs) {
40789
- try {
40790
- const decoded = decodeEventLog({
40791
- abi: dataRefinerRegistryAbi,
40792
- data: log.data,
40793
- topics: log.topics
40794
- });
40795
- if (decoded.eventName === "SchemaAdded") {
40796
- schemaId = Number(decoded.args.schemaId);
40797
- break;
40798
- }
40799
- } catch {
40800
- continue;
40801
- }
40802
- }
40803
- return {
40804
- schemaId,
40805
- transactionHash: txHash
40806
- };
40807
- } catch (error) {
40808
- console.error("Failed to add schema:", error);
40809
- throw new Error(
40810
- `Failed to add schema: ${error instanceof Error ? error.message : "Unknown error"}`
40811
- );
40812
- }
40813
- }
40814
- /**
40815
- * Retrieves a schema by its ID.
40816
- *
40817
- * @deprecated Since v2.0.0 - Use vana.schemas.get() instead
40818
- *
40819
- * Migration guide:
40820
- * ```typescript
40821
- * // Old way (deprecated):
40822
- * const schema = await vana.data.getSchema(schemaId);
40823
- *
40824
- * // New way:
40825
- * const schema = await vana.schemas.get(schemaId);
41418
+ * console.log(`Created refiner ${result.refinerId} in tx ${result.transactionHash}`);
40826
41419
  * ```
40827
- * @param schemaId - The schema ID to retrieve
40828
- * @returns Promise resolving to the schema information
40829
- */
40830
- async getSchema(schemaId) {
40831
- try {
40832
- const chainId = this.context.walletClient.chain?.id;
40833
- if (!chainId) {
40834
- throw new Error("Chain ID not available");
40835
- }
40836
- const dataRefinerRegistryAddress = getContractAddress(
40837
- chainId,
40838
- "DataRefinerRegistry"
40839
- );
40840
- const dataRefinerRegistryAbi = getAbi("DataRefinerRegistry");
40841
- const dataRefinerRegistry = getContract({
40842
- address: dataRefinerRegistryAddress,
40843
- abi: dataRefinerRegistryAbi,
40844
- client: this.context.walletClient
40845
- });
40846
- const schemaData = await dataRefinerRegistry.read.schemas([
40847
- BigInt(schemaId)
40848
- ]);
40849
- if (!schemaData) {
40850
- throw new Error("Schema not found");
40851
- }
40852
- const schemaObj = schemaData;
40853
- if (!schemaObj.name || !schemaObj.typ || !schemaObj.definitionUrl) {
40854
- throw new Error("Incomplete schema data");
40855
- }
40856
- return {
40857
- id: schemaId,
40858
- name: schemaObj.name,
40859
- type: schemaObj.typ,
40860
- definitionUrl: schemaObj.definitionUrl
40861
- };
40862
- } catch (error) {
40863
- console.error("Failed to get schema:", error);
40864
- throw new Error(
40865
- `Failed to get schema ${schemaId}: ${error instanceof Error ? error.message : "Unknown error"}`
40866
- );
40867
- }
40868
- }
40869
- /**
40870
- * Gets the total number of schemas in the registry.
40871
- *
40872
- * @deprecated Since v2.0.0 - Use vana.schemas.count() instead
40873
- *
40874
- * Migration guide:
40875
- * ```typescript
40876
- * // Old way (deprecated):
40877
- * const count = await vana.data.getSchemasCount();
40878
- *
40879
- * // New way:
40880
- * const count = await vana.schemas.count();
40881
- * ```
40882
- * @returns Promise resolving to the total schema count
40883
- */
40884
- async getSchemasCount() {
40885
- try {
40886
- const chainId = this.context.walletClient.chain?.id;
40887
- if (!chainId) {
40888
- throw new Error("Chain ID not available");
40889
- }
40890
- const dataRefinerRegistryAddress = getContractAddress(
40891
- chainId,
40892
- "DataRefinerRegistry"
40893
- );
40894
- const dataRefinerRegistryAbi = getAbi("DataRefinerRegistry");
40895
- const dataRefinerRegistry = getContract({
40896
- address: dataRefinerRegistryAddress,
40897
- abi: dataRefinerRegistryAbi,
40898
- client: this.context.walletClient
40899
- });
40900
- const count = await dataRefinerRegistry.read.schemasCount();
40901
- return Number(count);
40902
- } catch (error) {
40903
- console.error("Failed to get schemas count:", error);
40904
- return 0;
40905
- }
40906
- }
40907
- /**
40908
- * Adds a new refiner to the DataRefinerRegistry.
40909
- *
40910
- * @param params - Refiner parameters including DLP ID, name, schema ID, and instruction URL
40911
- * @returns Promise resolving to the new refiner ID and transaction hash
40912
41420
  */
40913
41421
  async addRefiner(params) {
40914
41422
  try {
@@ -40934,30 +41442,14 @@ var DataController = class {
40934
41442
  account: this.context.walletClient.account || await this.getUserAddress(),
40935
41443
  chain: this.context.walletClient.chain || null
40936
41444
  });
40937
- const receipt = await this.context.publicClient.waitForTransactionReceipt(
40938
- {
40939
- hash: txHash,
40940
- timeout: 3e4
40941
- }
41445
+ const txHandle = new TransactionHandle(
41446
+ this.context,
41447
+ txHash,
41448
+ "addRefiner"
40942
41449
  );
40943
- let refinerId = 0;
40944
- for (const log of receipt.logs) {
40945
- try {
40946
- const decoded = decodeEventLog({
40947
- abi: dataRefinerRegistryAbi,
40948
- data: log.data,
40949
- topics: log.topics
40950
- });
40951
- if (decoded.eventName === "RefinerAdded") {
40952
- refinerId = Number(decoded.args.refinerId);
40953
- break;
40954
- }
40955
- } catch {
40956
- continue;
40957
- }
40958
- }
41450
+ const result = await txHandle.waitForEvents();
40959
41451
  return {
40960
- refinerId,
41452
+ refinerId: Number(result.refinerId),
40961
41453
  transactionHash: txHash
40962
41454
  };
40963
41455
  } catch (error) {
@@ -40970,8 +41462,25 @@ var DataController = class {
40970
41462
  /**
40971
41463
  * Retrieves a refiner by its ID.
40972
41464
  *
40973
- * @param refinerId - The refiner ID to retrieve
40974
- * @returns Promise resolving to the refiner information
41465
+ * @remarks
41466
+ * Queries the DataRefinerRegistry contract to get complete information about
41467
+ * a specific refiner including its DLP association, schema, and instructions.
41468
+ *
41469
+ * @param refinerId - The numeric refiner ID to retrieve
41470
+ * @returns Promise resolving to the refiner information object
41471
+ * @throws {Error} When chain ID is not available - "Chain ID not available"
41472
+ * @throws {Error} When refiner doesn't exist - "Refiner with ID {refinerId} does not exist"
41473
+ * @throws {Error} When contract read fails - "Failed to fetch refiner: {error}"
41474
+ * @example
41475
+ * ```typescript
41476
+ * const refiner = await vana.data.getRefiner(1);
41477
+ * console.log({
41478
+ * name: refiner.name,
41479
+ * dlp: refiner.dlpId,
41480
+ * schema: refiner.schemaId,
41481
+ * instructions: refiner.refinementInstructionUrl
41482
+ * });
41483
+ * ```
40975
41484
  */
40976
41485
  async getRefiner(refinerId) {
40977
41486
  try {
@@ -40984,7 +41493,7 @@ var DataController = class {
40984
41493
  "DataRefinerRegistry"
40985
41494
  );
40986
41495
  const dataRefinerRegistryAbi = getAbi("DataRefinerRegistry");
40987
- const dataRefinerRegistry = getContract({
41496
+ const dataRefinerRegistry = getContract2({
40988
41497
  address: dataRefinerRegistryAddress,
40989
41498
  abi: dataRefinerRegistryAbi,
40990
41499
  client: this.context.walletClient
@@ -41013,8 +41522,21 @@ var DataController = class {
41013
41522
  /**
41014
41523
  * Validates if a schema ID exists in the registry.
41015
41524
  *
41016
- * @param schemaId - The schema ID to validate
41017
- * @returns Promise resolving to boolean indicating if the schema ID is valid
41525
+ * @remarks
41526
+ * Checks the DataRefinerRegistry contract to determine if a given schema ID
41527
+ * has been registered and is available for use.
41528
+ *
41529
+ * @param schemaId - The numeric schema ID to validate
41530
+ * @returns Promise resolving to true if schema exists, false otherwise
41531
+ * @example
41532
+ * ```typescript
41533
+ * const isValid = await vana.data.isValidSchemaId(42);
41534
+ * if (isValid) {
41535
+ * console.log('Schema 42 is available for use');
41536
+ * } else {
41537
+ * console.log('Schema 42 does not exist');
41538
+ * }
41539
+ * ```
41018
41540
  */
41019
41541
  async isValidSchemaId(schemaId) {
41020
41542
  try {
@@ -41027,7 +41549,7 @@ var DataController = class {
41027
41549
  "DataRefinerRegistry"
41028
41550
  );
41029
41551
  const dataRefinerRegistryAbi = getAbi("DataRefinerRegistry");
41030
- const dataRefinerRegistry = getContract({
41552
+ const dataRefinerRegistry = getContract2({
41031
41553
  address: dataRefinerRegistryAddress,
41032
41554
  abi: dataRefinerRegistryAbi,
41033
41555
  client: this.context.walletClient
@@ -41044,7 +41566,16 @@ var DataController = class {
41044
41566
  /**
41045
41567
  * Gets the total number of refiners in the registry.
41046
41568
  *
41569
+ * @remarks
41570
+ * Queries the DataRefinerRegistry contract to get the total count of all
41571
+ * registered refiners across all DLPs.
41572
+ *
41047
41573
  * @returns Promise resolving to the total refiner count
41574
+ * @example
41575
+ * ```typescript
41576
+ * const count = await vana.data.getRefinersCount();
41577
+ * console.log(`Total refiners registered: ${count}`);
41578
+ * ```
41048
41579
  */
41049
41580
  async getRefinersCount() {
41050
41581
  try {
@@ -41057,7 +41588,7 @@ var DataController = class {
41057
41588
  "DataRefinerRegistry"
41058
41589
  );
41059
41590
  const dataRefinerRegistryAbi = getAbi("DataRefinerRegistry");
41060
- const dataRefinerRegistry = getContract({
41591
+ const dataRefinerRegistry = getContract2({
41061
41592
  address: dataRefinerRegistryAddress,
41062
41593
  abi: dataRefinerRegistryAbi,
41063
41594
  client: this.context.walletClient
@@ -41072,8 +41603,24 @@ var DataController = class {
41072
41603
  /**
41073
41604
  * Updates the schema ID for an existing refiner.
41074
41605
  *
41075
- * @param params - Parameters including refiner ID and new schema ID
41606
+ * @remarks
41607
+ * Allows the owner of a refiner to update its associated schema ID.
41608
+ * This is useful when refiner output format needs to change.
41609
+ *
41610
+ * @param params - Update parameters
41611
+ * @param params.refinerId - The refiner ID to update
41612
+ * @param params.newSchemaId - The new schema ID to set
41076
41613
  * @returns Promise resolving to the transaction hash
41614
+ * @throws {Error} When chain ID is not available - "Chain ID not available"
41615
+ * @throws {Error} When transaction fails - "Failed to update schema ID: {error}"
41616
+ * @example
41617
+ * ```typescript
41618
+ * const result = await vana.data.updateSchemaId({
41619
+ * refinerId: 1,
41620
+ * newSchemaId: 55
41621
+ * });
41622
+ * console.log(`Schema updated in tx ${result.transactionHash}`);
41623
+ * ```
41077
41624
  */
41078
41625
  async updateSchemaId(params) {
41079
41626
  try {
@@ -41125,27 +41672,19 @@ var DataController = class {
41125
41672
  */
41126
41673
  async uploadFileWithPermissions(data, permissions, filename, providerName) {
41127
41674
  try {
41128
- const userEncryptionKey = await generateEncryptionKey(
41129
- this.context.walletClient,
41130
- this.context.platform,
41131
- DEFAULT_ENCRYPTION_SEED
41132
- );
41133
- const encryptedData = await encryptBlobWithSignedKey(
41675
+ const uploadResult = await this.uploadToStorage(
41134
41676
  data,
41135
- userEncryptionKey,
41136
- this.context.platform
41137
- );
41138
- if (!this.context.storageManager) {
41139
- throw new Error(
41140
- "Storage manager not configured. Please provide storage providers in VanaConfig."
41141
- );
41142
- }
41143
- const uploadResult = await this.context.storageManager.upload(
41144
- encryptedData,
41145
41677
  filename,
41678
+ true,
41679
+ // Always encrypt for uploadFileWithPermissions
41146
41680
  providerName
41147
41681
  );
41148
41682
  const userAddress = await this.getUserAddress();
41683
+ const userEncryptionKey = await generateEncryptionKey(
41684
+ this.context.walletClient,
41685
+ this.context.platform,
41686
+ DEFAULT_ENCRYPTION_SEED
41687
+ );
41149
41688
  const encryptedPermissions = await Promise.all(
41150
41689
  permissions.map(async (permission) => {
41151
41690
  const encryptedKey = await encryptWithWalletPublicKey(
@@ -41186,6 +41725,70 @@ var DataController = class {
41186
41725
  );
41187
41726
  }
41188
41727
  }
41728
+ /**
41729
+ * Uploads content to storage without registering it on the blockchain.
41730
+ * This method only handles the storage upload and returns the file URL.
41731
+ *
41732
+ * @param content - The content to upload (string, Blob, Buffer, or object - objects will be JSON stringified)
41733
+ * @param filename - Optional filename for the uploaded file (defaults to timestamp-based name)
41734
+ * @param encrypt - Optional flag to encrypt the content before upload
41735
+ * @param providerName - Optional specific storage provider to use
41736
+ * @returns Promise resolving to the storage upload result with url, size, and contentType
41737
+ */
41738
+ async uploadToStorage(content, filename, encrypt = false, providerName) {
41739
+ try {
41740
+ let blob;
41741
+ if (content instanceof Blob) {
41742
+ blob = content;
41743
+ } else if (typeof content === "string") {
41744
+ blob = new Blob([content], { type: "text/plain" });
41745
+ } else if (content instanceof Buffer) {
41746
+ const arrayBuffer = content.buffer.slice(
41747
+ content.byteOffset,
41748
+ content.byteOffset + content.byteLength
41749
+ );
41750
+ blob = new Blob([arrayBuffer], { type: "application/octet-stream" });
41751
+ } else {
41752
+ blob = new Blob([JSON.stringify(content)], {
41753
+ type: "application/json"
41754
+ });
41755
+ }
41756
+ let finalBlob = blob;
41757
+ if (encrypt) {
41758
+ const encryptionKey = await generateEncryptionKey(
41759
+ this.context.walletClient,
41760
+ this.context.platform,
41761
+ DEFAULT_ENCRYPTION_SEED
41762
+ );
41763
+ finalBlob = await encryptBlobWithSignedKey(
41764
+ blob,
41765
+ encryptionKey,
41766
+ this.context.platform
41767
+ );
41768
+ }
41769
+ if (!this.context.storageManager) {
41770
+ if (this.context.validateStorageRequired) {
41771
+ this.context.validateStorageRequired();
41772
+ throw new Error("Storage validation failed");
41773
+ } else {
41774
+ throw new Error(
41775
+ "Storage manager not configured. Please provide storage providers in VanaConfig."
41776
+ );
41777
+ }
41778
+ }
41779
+ const finalFilename = filename || `upload-${Date.now()}.dat`;
41780
+ const uploadResult = await this.context.storageManager.upload(
41781
+ finalBlob,
41782
+ finalFilename,
41783
+ providerName
41784
+ );
41785
+ return uploadResult;
41786
+ } catch (error) {
41787
+ throw new Error(
41788
+ `Upload failed: ${error instanceof Error ? error.message : "Unknown error"}`
41789
+ );
41790
+ }
41791
+ }
41189
41792
  /**
41190
41793
  * Adds a permission for a party to access an existing file.
41191
41794
  *
@@ -41213,8 +41816,7 @@ var DataController = class {
41213
41816
  * ```
41214
41817
  */
41215
41818
  async addPermissionToFile(fileId, account, publicKey) {
41216
- const txHash = await this.submitFilePermission(fileId, account, publicKey);
41217
- return parseTransactionResult(this.context, txHash, "addFilePermission");
41819
+ return await this.submitFilePermission(fileId, account, publicKey);
41218
41820
  }
41219
41821
  /**
41220
41822
  * Submits a file permission transaction and returns the transaction hash immediately.
@@ -41258,7 +41860,11 @@ var DataController = class {
41258
41860
  account: this.context.walletClient.account || await this.getUserAddress(),
41259
41861
  chain: this.context.walletClient.chain || null
41260
41862
  });
41261
- return txHash;
41863
+ return new TransactionHandle(
41864
+ this.context,
41865
+ txHash,
41866
+ "addFilePermission"
41867
+ );
41262
41868
  } catch (error) {
41263
41869
  console.error("Failed to add permission to file:", error);
41264
41870
  throw new Error(
@@ -41281,7 +41887,7 @@ var DataController = class {
41281
41887
  }
41282
41888
  const dataRegistryAddress = getContractAddress(chainId, "DataRegistry");
41283
41889
  const dataRegistryAbi = getAbi("DataRegistry");
41284
- const dataRegistry = getContract({
41890
+ const dataRegistry = getContract2({
41285
41891
  address: dataRegistryAddress,
41286
41892
  abi: dataRegistryAbi,
41287
41893
  client: this.context.walletClient
@@ -41605,7 +42211,7 @@ var DataController = class {
41605
42211
  */
41606
42212
  async getValidatedSchema(schemaId) {
41607
42213
  try {
41608
- const schema = await this.getSchema(schemaId);
42214
+ const schema = await fetchSchemaFromChain(this.context, schemaId);
41609
42215
  const dataSchema = await this.fetchAndValidateSchema(
41610
42216
  schema.definitionUrl
41611
42217
  );
@@ -41629,8 +42235,203 @@ var DataController = class {
41629
42235
  }
41630
42236
  };
41631
42237
 
42238
+ // src/generated/subgraph.ts
42239
+ var GetSchemaDocument = {
42240
+ kind: "Document",
42241
+ definitions: [
42242
+ {
42243
+ kind: "OperationDefinition",
42244
+ operation: "query",
42245
+ name: { kind: "Name", value: "GetSchema" },
42246
+ variableDefinitions: [
42247
+ {
42248
+ kind: "VariableDefinition",
42249
+ variable: { kind: "Variable", name: { kind: "Name", value: "id" } },
42250
+ type: {
42251
+ kind: "NonNullType",
42252
+ type: { kind: "NamedType", name: { kind: "Name", value: "ID" } }
42253
+ }
42254
+ }
42255
+ ],
42256
+ selectionSet: {
42257
+ kind: "SelectionSet",
42258
+ selections: [
42259
+ {
42260
+ kind: "Field",
42261
+ name: { kind: "Name", value: "schema" },
42262
+ arguments: [
42263
+ {
42264
+ kind: "Argument",
42265
+ name: { kind: "Name", value: "id" },
42266
+ value: {
42267
+ kind: "Variable",
42268
+ name: { kind: "Name", value: "id" }
42269
+ }
42270
+ }
42271
+ ],
42272
+ selectionSet: {
42273
+ kind: "SelectionSet",
42274
+ selections: [
42275
+ { kind: "Field", name: { kind: "Name", value: "id" } },
42276
+ { kind: "Field", name: { kind: "Name", value: "name" } },
42277
+ { kind: "Field", name: { kind: "Name", value: "dialect" } },
42278
+ {
42279
+ kind: "Field",
42280
+ name: { kind: "Name", value: "definitionUrl" }
42281
+ },
42282
+ { kind: "Field", name: { kind: "Name", value: "createdAt" } },
42283
+ {
42284
+ kind: "Field",
42285
+ name: { kind: "Name", value: "createdAtBlock" }
42286
+ },
42287
+ {
42288
+ kind: "Field",
42289
+ name: { kind: "Name", value: "createdTxHash" }
42290
+ },
42291
+ {
42292
+ kind: "Field",
42293
+ name: { kind: "Name", value: "refiners" },
42294
+ selectionSet: {
42295
+ kind: "SelectionSet",
42296
+ selections: [
42297
+ { kind: "Field", name: { kind: "Name", value: "id" } },
42298
+ { kind: "Field", name: { kind: "Name", value: "name" } },
42299
+ { kind: "Field", name: { kind: "Name", value: "owner" } }
42300
+ ]
42301
+ }
42302
+ }
42303
+ ]
42304
+ }
42305
+ }
42306
+ ]
42307
+ }
42308
+ }
42309
+ ]
42310
+ };
42311
+ var ListSchemasDocument = {
42312
+ kind: "Document",
42313
+ definitions: [
42314
+ {
42315
+ kind: "OperationDefinition",
42316
+ operation: "query",
42317
+ name: { kind: "Name", value: "ListSchemas" },
42318
+ variableDefinitions: [
42319
+ {
42320
+ kind: "VariableDefinition",
42321
+ variable: {
42322
+ kind: "Variable",
42323
+ name: { kind: "Name", value: "first" }
42324
+ },
42325
+ type: {
42326
+ kind: "NonNullType",
42327
+ type: { kind: "NamedType", name: { kind: "Name", value: "Int" } }
42328
+ }
42329
+ },
42330
+ {
42331
+ kind: "VariableDefinition",
42332
+ variable: { kind: "Variable", name: { kind: "Name", value: "skip" } },
42333
+ type: {
42334
+ kind: "NonNullType",
42335
+ type: { kind: "NamedType", name: { kind: "Name", value: "Int" } }
42336
+ }
42337
+ }
42338
+ ],
42339
+ selectionSet: {
42340
+ kind: "SelectionSet",
42341
+ selections: [
42342
+ {
42343
+ kind: "Field",
42344
+ name: { kind: "Name", value: "schemas" },
42345
+ arguments: [
42346
+ {
42347
+ kind: "Argument",
42348
+ name: { kind: "Name", value: "first" },
42349
+ value: {
42350
+ kind: "Variable",
42351
+ name: { kind: "Name", value: "first" }
42352
+ }
42353
+ },
42354
+ {
42355
+ kind: "Argument",
42356
+ name: { kind: "Name", value: "skip" },
42357
+ value: {
42358
+ kind: "Variable",
42359
+ name: { kind: "Name", value: "skip" }
42360
+ }
42361
+ },
42362
+ {
42363
+ kind: "Argument",
42364
+ name: { kind: "Name", value: "orderBy" },
42365
+ value: { kind: "EnumValue", value: "createdAt" }
42366
+ },
42367
+ {
42368
+ kind: "Argument",
42369
+ name: { kind: "Name", value: "orderDirection" },
42370
+ value: { kind: "EnumValue", value: "desc" }
42371
+ }
42372
+ ],
42373
+ selectionSet: {
42374
+ kind: "SelectionSet",
42375
+ selections: [
42376
+ { kind: "Field", name: { kind: "Name", value: "id" } },
42377
+ { kind: "Field", name: { kind: "Name", value: "name" } },
42378
+ { kind: "Field", name: { kind: "Name", value: "dialect" } },
42379
+ {
42380
+ kind: "Field",
42381
+ name: { kind: "Name", value: "definitionUrl" }
42382
+ },
42383
+ { kind: "Field", name: { kind: "Name", value: "createdAt" } },
42384
+ {
42385
+ kind: "Field",
42386
+ name: { kind: "Name", value: "createdAtBlock" }
42387
+ },
42388
+ {
42389
+ kind: "Field",
42390
+ name: { kind: "Name", value: "createdTxHash" }
42391
+ }
42392
+ ]
42393
+ }
42394
+ }
42395
+ ]
42396
+ }
42397
+ }
42398
+ ]
42399
+ };
42400
+ var CountSchemasDocument = {
42401
+ kind: "Document",
42402
+ definitions: [
42403
+ {
42404
+ kind: "OperationDefinition",
42405
+ operation: "query",
42406
+ name: { kind: "Name", value: "CountSchemas" },
42407
+ selectionSet: {
42408
+ kind: "SelectionSet",
42409
+ selections: [
42410
+ {
42411
+ kind: "Field",
42412
+ name: { kind: "Name", value: "schemas" },
42413
+ arguments: [
42414
+ {
42415
+ kind: "Argument",
42416
+ name: { kind: "Name", value: "first" },
42417
+ value: { kind: "IntValue", value: "1000" }
42418
+ }
42419
+ ],
42420
+ selectionSet: {
42421
+ kind: "SelectionSet",
42422
+ selections: [
42423
+ { kind: "Field", name: { kind: "Name", value: "id" } }
42424
+ ]
42425
+ }
42426
+ }
42427
+ ]
42428
+ }
42429
+ }
42430
+ ]
42431
+ };
42432
+
41632
42433
  // src/controllers/schemas.ts
41633
- import { getContract as getContract2, decodeEventLog as decodeEventLog2 } from "viem";
42434
+ import { print } from "graphql";
41634
42435
  var SchemaController = class {
41635
42436
  constructor(context) {
41636
42437
  this.context = context;
@@ -41732,30 +42533,14 @@ var SchemaController = class {
41732
42533
  account: this.context.walletClient.account || userAddress,
41733
42534
  chain: this.context.walletClient.chain || null
41734
42535
  });
41735
- const receipt = await this.context.publicClient.waitForTransactionReceipt(
41736
- {
41737
- hash: txHash,
41738
- timeout: 3e4
41739
- // 30 seconds timeout
41740
- }
42536
+ const txHandle = new TransactionHandle(
42537
+ this.context,
42538
+ txHash,
42539
+ "addSchema"
41741
42540
  );
41742
- let schemaId = 0;
41743
- for (const log of receipt.logs) {
41744
- try {
41745
- const decoded = decodeEventLog2({
41746
- abi: dataRefinerRegistryAbi,
41747
- data: log.data,
41748
- topics: log.topics
41749
- });
41750
- if (decoded.eventName === "SchemaAdded") {
41751
- schemaId = Number(decoded.args.schemaId);
41752
- break;
41753
- }
41754
- } catch {
41755
- }
41756
- }
42541
+ const result = await txHandle.waitForEvents();
41757
42542
  return {
41758
- schemaId,
42543
+ schemaId: Number(result.schemaId),
41759
42544
  definitionUrl: uploadResult.url,
41760
42545
  transactionHash: txHash
41761
42546
  };
@@ -41772,46 +42557,32 @@ var SchemaController = class {
41772
42557
  * Retrieves a schema by its ID.
41773
42558
  *
41774
42559
  * @param schemaId - The ID of the schema to retrieve
42560
+ * @param options - Optional parameters
42561
+ * @param options.subgraphUrl - Custom subgraph URL to use instead of default
41775
42562
  * @returns Promise resolving to the schema object
41776
42563
  * @throws {Error} When the schema is not found or chain is unavailable
41777
42564
  * @example
41778
42565
  * ```typescript
41779
42566
  * const schema = await vana.schemas.get(1);
41780
42567
  * console.log(`Schema: ${schema.name} (${schema.type})`);
42568
+ *
42569
+ * // With custom subgraph
42570
+ * const schema = await vana.schemas.get(1, {
42571
+ * subgraphUrl: 'https://custom-subgraph.com/graphql'
42572
+ * });
41781
42573
  * ```
41782
42574
  */
41783
- async get(schemaId) {
41784
- try {
41785
- const chainId = this.context.walletClient.chain?.id;
41786
- if (!chainId) {
41787
- throw new Error("Chain ID not available");
41788
- }
41789
- const dataRefinerRegistryAddress = getContractAddress(
41790
- chainId,
41791
- "DataRefinerRegistry"
41792
- );
41793
- const dataRefinerRegistryAbi = getAbi("DataRefinerRegistry");
41794
- const dataRefinerRegistry = getContract2({
41795
- address: dataRefinerRegistryAddress,
41796
- abi: dataRefinerRegistryAbi,
41797
- client: this.context.publicClient
41798
- });
41799
- const schemaData = await dataRefinerRegistry.read.schemas([
41800
- BigInt(schemaId)
41801
- ]);
41802
- if (!schemaData) {
41803
- throw new Error(`Schema with ID ${schemaId} not found`);
41804
- }
41805
- const schemaObj = schemaData;
41806
- if (!schemaObj.name || !schemaObj.typ || !schemaObj.definitionUrl) {
41807
- throw new Error("Incomplete schema data");
42575
+ async get(schemaId, options = {}) {
42576
+ const subgraphUrl = options.subgraphUrl || this.context.subgraphUrl;
42577
+ if (subgraphUrl) {
42578
+ try {
42579
+ return await this._getSchemaViaSubgraph({ schemaId, subgraphUrl });
42580
+ } catch (error) {
42581
+ console.debug("Subgraph query failed, falling back to RPC:", error);
41808
42582
  }
41809
- return {
41810
- id: schemaId,
41811
- name: schemaObj.name,
41812
- type: schemaObj.typ,
41813
- definitionUrl: schemaObj.definitionUrl
41814
- };
42583
+ }
42584
+ try {
42585
+ return await fetchSchemaFromChain(this.context, schemaId);
41815
42586
  } catch (error) {
41816
42587
  throw new Error(
41817
42588
  `Failed to get schema: ${error instanceof Error ? error.message : "Unknown error"}`
@@ -41821,32 +42592,32 @@ var SchemaController = class {
41821
42592
  /**
41822
42593
  * Gets the total number of schemas registered on the network.
41823
42594
  *
42595
+ * @param options - Optional parameters
42596
+ * @param options.subgraphUrl - Custom subgraph URL to use instead of default
41824
42597
  * @returns Promise resolving to the total schema count
41825
42598
  * @throws {Error} When the count cannot be retrieved
41826
42599
  * @example
41827
42600
  * ```typescript
41828
42601
  * const count = await vana.schemas.count();
41829
42602
  * console.log(`Total schemas: ${count}`);
42603
+ *
42604
+ * // With custom subgraph
42605
+ * const count = await vana.schemas.count({
42606
+ * subgraphUrl: 'https://custom-subgraph.com/graphql'
42607
+ * });
41830
42608
  * ```
41831
42609
  */
41832
- async count() {
41833
- try {
41834
- const chainId = this.context.walletClient.chain?.id;
41835
- if (!chainId) {
41836
- throw new Error("Chain ID not available");
42610
+ async count(options = {}) {
42611
+ const subgraphUrl = options.subgraphUrl || this.context.subgraphUrl;
42612
+ if (subgraphUrl) {
42613
+ try {
42614
+ return await this._countSchemasViaSubgraph({ subgraphUrl });
42615
+ } catch (error) {
42616
+ console.debug("Subgraph query failed, falling back to RPC:", error);
41837
42617
  }
41838
- const dataRefinerRegistryAddress = getContractAddress(
41839
- chainId,
41840
- "DataRefinerRegistry"
41841
- );
41842
- const dataRefinerRegistryAbi = getAbi("DataRefinerRegistry");
41843
- const dataRefinerRegistry = getContract2({
41844
- address: dataRefinerRegistryAddress,
41845
- abi: dataRefinerRegistryAbi,
41846
- client: this.context.publicClient
41847
- });
41848
- const count = await dataRefinerRegistry.read.schemasCount();
41849
- return Number(count);
42618
+ }
42619
+ try {
42620
+ return await fetchSchemaCountFromChain(this.context);
41850
42621
  } catch (error) {
41851
42622
  throw new Error(
41852
42623
  `Failed to get schemas count: ${error instanceof Error ? error.message : "Unknown error"}`
@@ -41859,6 +42630,7 @@ var SchemaController = class {
41859
42630
  * @param options - Optional parameters for listing schemas
41860
42631
  * @param options.limit - Maximum number of schemas to return
41861
42632
  * @param options.offset - Number of schemas to skip
42633
+ * @param options.subgraphUrl - Custom subgraph URL to use instead of default
41862
42634
  * @returns Promise resolving to an array of schemas
41863
42635
  * @example
41864
42636
  * ```typescript
@@ -41867,23 +42639,78 @@ var SchemaController = class {
41867
42639
  *
41868
42640
  * // Get schemas with pagination
41869
42641
  * const schemas = await vana.schemas.list({ limit: 10, offset: 0 });
42642
+ *
42643
+ * // With custom subgraph
42644
+ * const schemas = await vana.schemas.list({
42645
+ * limit: 10,
42646
+ * offset: 0,
42647
+ * subgraphUrl: 'https://custom-subgraph.com/graphql'
42648
+ * });
41870
42649
  * ```
41871
42650
  */
41872
42651
  async list(options = {}) {
41873
42652
  const { limit = 100, offset = 0 } = options;
42653
+ const subgraphUrl = options.subgraphUrl || this.context.subgraphUrl;
42654
+ if (subgraphUrl) {
42655
+ try {
42656
+ return await this._listSchemasViaSubgraph({
42657
+ limit,
42658
+ offset,
42659
+ subgraphUrl
42660
+ });
42661
+ } catch (error) {
42662
+ console.debug("Subgraph query failed, falling back to RPC:", error);
42663
+ }
42664
+ }
41874
42665
  try {
41875
42666
  const totalCount = await this.count();
41876
- const schemas = [];
41877
42667
  const start = offset;
41878
42668
  const end = Math.min(start + limit, totalCount);
42669
+ if (end <= start) {
42670
+ return [];
42671
+ }
42672
+ const chainId = this.context.walletClient.chain?.id;
42673
+ if (!chainId) {
42674
+ throw new Error("Chain ID not available");
42675
+ }
42676
+ const dataRefinerRegistryAddress = getContractAddress(
42677
+ chainId,
42678
+ "DataRefinerRegistry"
42679
+ );
42680
+ const dataRefinerRegistryAbi = getAbi("DataRefinerRegistry");
42681
+ const schemaCalls = [];
41879
42682
  for (let i = start; i < end; i++) {
41880
- try {
41881
- const schema = await this.get(i + 1);
41882
- schemas.push(schema);
41883
- } catch (error) {
41884
- console.warn(`Failed to retrieve schema ${i + 1}:`, error);
41885
- }
42683
+ schemaCalls.push({
42684
+ address: dataRefinerRegistryAddress,
42685
+ abi: dataRefinerRegistryAbi,
42686
+ functionName: "schemas",
42687
+ args: [BigInt(i + 1)]
42688
+ // Schema IDs are 1-based
42689
+ });
41886
42690
  }
42691
+ const schemaResults = await gasAwareMulticall(this.context.publicClient, {
42692
+ contracts: schemaCalls,
42693
+ allowFailure: true
42694
+ });
42695
+ const schemas = [];
42696
+ schemaResults.forEach((result, index) => {
42697
+ if (result.status === "success" && result.result) {
42698
+ const schemaId = start + index + 1;
42699
+ const schemaData = result.result;
42700
+ if (schemaData.name && schemaData.dialect && schemaData.definitionUrl) {
42701
+ schemas.push({
42702
+ id: schemaId,
42703
+ name: schemaData.name,
42704
+ dialect: schemaData.dialect,
42705
+ definitionUrl: schemaData.definitionUrl
42706
+ });
42707
+ } else {
42708
+ console.warn(`Incomplete schema data for ID ${schemaId}`);
42709
+ }
42710
+ } else {
42711
+ console.warn(`Failed to retrieve schema ${start + index + 1}`);
42712
+ }
42713
+ });
41887
42714
  return schemas;
41888
42715
  } catch (error) {
41889
42716
  throw new Error(
@@ -41914,7 +42741,7 @@ var SchemaController = class {
41914
42741
  address: dataRefinerRegistryAddress,
41915
42742
  abi: dataRefinerRegistryAbi,
41916
42743
  functionName: "addSchema",
41917
- args: [params.name, params.type, params.definitionUrl],
42744
+ args: [params.name, params.dialect, params.definitionUrl],
41918
42745
  account: this.context.walletClient.account || userAddress,
41919
42746
  chain: this.context.walletClient.chain || null
41920
42747
  });
@@ -41929,6 +42756,119 @@ var SchemaController = class {
41929
42756
  );
41930
42757
  }
41931
42758
  }
42759
+ /**
42760
+ * Internal method: Query schema via subgraph
42761
+ *
42762
+ * @param params - Query parameters
42763
+ * @param params.schemaId - The ID of the schema to retrieve
42764
+ * @param params.subgraphUrl - The subgraph URL to query
42765
+ * @returns Promise resolving to the schema object
42766
+ * @private
42767
+ */
42768
+ async _getSchemaViaSubgraph(params) {
42769
+ const { schemaId, subgraphUrl } = params;
42770
+ const response = await fetch(subgraphUrl, {
42771
+ method: "POST",
42772
+ headers: { "Content-Type": "application/json" },
42773
+ body: JSON.stringify({
42774
+ query: print(GetSchemaDocument),
42775
+ variables: { id: schemaId.toString() }
42776
+ })
42777
+ });
42778
+ if (!response.ok) {
42779
+ throw new Error(
42780
+ `Subgraph request failed: ${response.status} ${response.statusText}`
42781
+ );
42782
+ }
42783
+ const result = await response.json();
42784
+ if (result.errors) {
42785
+ throw new Error(
42786
+ `Subgraph query errors: ${result.errors.map((e) => e.message).join(", ")}`
42787
+ );
42788
+ }
42789
+ if (!result.data?.schema) {
42790
+ throw new Error(`Schema ${schemaId} not found in subgraph`);
42791
+ }
42792
+ const subgraphSchema = result.data.schema;
42793
+ return {
42794
+ id: parseInt(subgraphSchema.id),
42795
+ name: subgraphSchema.name,
42796
+ dialect: subgraphSchema.dialect,
42797
+ definitionUrl: subgraphSchema.definitionUrl
42798
+ };
42799
+ }
42800
+ /**
42801
+ * Internal method: List schemas via subgraph
42802
+ *
42803
+ * @param params - Query parameters
42804
+ * @param params.limit - Maximum number of schemas to return
42805
+ * @param params.offset - Number of schemas to skip
42806
+ * @param params.subgraphUrl - The subgraph URL to query
42807
+ * @returns Promise resolving to an array of schemas
42808
+ * @private
42809
+ */
42810
+ async _listSchemasViaSubgraph(params) {
42811
+ const { limit, offset, subgraphUrl } = params;
42812
+ const response = await fetch(subgraphUrl, {
42813
+ method: "POST",
42814
+ headers: { "Content-Type": "application/json" },
42815
+ body: JSON.stringify({
42816
+ query: print(ListSchemasDocument),
42817
+ variables: { first: limit, skip: offset }
42818
+ })
42819
+ });
42820
+ if (!response.ok) {
42821
+ throw new Error(
42822
+ `Subgraph request failed: ${response.status} ${response.statusText}`
42823
+ );
42824
+ }
42825
+ const result = await response.json();
42826
+ if (result.errors) {
42827
+ throw new Error(
42828
+ `Subgraph query errors: ${result.errors.map((e) => e.message).join(", ")}`
42829
+ );
42830
+ }
42831
+ if (!result.data?.schemas) {
42832
+ return [];
42833
+ }
42834
+ return result.data.schemas.map((schema) => ({
42835
+ id: parseInt(schema.id),
42836
+ name: schema.name,
42837
+ dialect: schema.dialect,
42838
+ definitionUrl: schema.definitionUrl
42839
+ }));
42840
+ }
42841
+ /**
42842
+ * Internal method: Count schemas via subgraph
42843
+ *
42844
+ * @param params - Query parameters
42845
+ * @param params.subgraphUrl - The subgraph URL to query
42846
+ * @returns Promise resolving to the total schema count
42847
+ * @private
42848
+ */
42849
+ async _countSchemasViaSubgraph(params) {
42850
+ const { subgraphUrl } = params;
42851
+ const response = await fetch(subgraphUrl, {
42852
+ method: "POST",
42853
+ headers: { "Content-Type": "application/json" },
42854
+ body: JSON.stringify({
42855
+ query: print(CountSchemasDocument),
42856
+ variables: {}
42857
+ })
42858
+ });
42859
+ if (!response.ok) {
42860
+ throw new Error(
42861
+ `Subgraph request failed: ${response.status} ${response.statusText}`
42862
+ );
42863
+ }
42864
+ const result = await response.json();
42865
+ if (result.errors) {
42866
+ throw new Error(
42867
+ `Subgraph query errors: ${result.errors.map((e) => e.message).join(", ")}`
42868
+ );
42869
+ }
42870
+ return result.data?.schemas?.length || 0;
42871
+ }
41932
42872
  /**
41933
42873
  * Gets the user's wallet address.
41934
42874
  *
@@ -44016,7 +44956,7 @@ var vanaMainnet2 = {
44016
44956
  url: "https://vanascan.io"
44017
44957
  }
44018
44958
  },
44019
- subgraphUrl: "https://api.goldsky.com/api/public/project_cm168cz887zva010j39il7a6p/subgraphs/vana/7.0.6/gn"
44959
+ subgraphUrl: "https://api.goldsky.com/api/public/project_cm168cz887zva010j39il7a6p/subgraphs/vana/7.0.7/gn"
44020
44960
  };
44021
44961
  var moksha = {
44022
44962
  id: 14800,
@@ -44037,7 +44977,7 @@ var moksha = {
44037
44977
  url: "https://moksha.vanascan.io"
44038
44978
  }
44039
44979
  },
44040
- subgraphUrl: "https://api.goldsky.com/api/public/project_cm168cz887zva010j39il7a6p/subgraphs/moksha/7.0.6/gn"
44980
+ subgraphUrl: "https://api.goldsky.com/api/public/project_cm168cz887zva010j39il7a6p/subgraphs/moksha/7.0.7/gn"
44041
44981
  };
44042
44982
  function getChainConfig(chainId) {
44043
44983
  switch (chainId) {
@@ -45380,6 +46320,7 @@ export {
45380
46320
  SignatureError,
45381
46321
  StorageError,
45382
46322
  StorageManager,
46323
+ TransactionHandle,
45383
46324
  UserRejectedRequestError,
45384
46325
  Vana,
45385
46326
  VanaBrowserImpl,