@opendatalabs/vana-sdk 0.1.0-alpha.8eb4e46 → 0.1.0-alpha.9a32094

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.
@@ -27,6 +27,28 @@ function parseEncryptedDataBuffer(encryptedBuffer) {
27
27
  mac: encryptedBuffer.slice(-32)
28
28
  };
29
29
  }
30
+ function toBase64(str) {
31
+ if (typeof Buffer !== "undefined") {
32
+ return Buffer.from(str, "utf8").toString("base64");
33
+ } else if (typeof btoa !== "undefined") {
34
+ return btoa(str);
35
+ } else {
36
+ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
37
+ let result = "";
38
+ let i = 0;
39
+ while (i < str.length) {
40
+ const a = str.charCodeAt(i++);
41
+ const b = i < str.length ? str.charCodeAt(i++) : 0;
42
+ const c = i < str.length ? str.charCodeAt(i++) : 0;
43
+ const bitmap = a << 16 | b << 8 | c;
44
+ result += chars.charAt(bitmap >> 18 & 63);
45
+ result += chars.charAt(bitmap >> 12 & 63);
46
+ result += i - 2 < str.length ? chars.charAt(bitmap >> 6 & 63) : "=";
47
+ result += i - 1 < str.length ? chars.charAt(bitmap & 63) : "=";
48
+ }
49
+ return result;
50
+ }
51
+ }
30
52
  var init_crypto_utils = __esm({
31
53
  "src/platform/shared/crypto-utils.ts"() {
32
54
  "use strict";
@@ -189,7 +211,7 @@ __export(browser_exports, {
189
211
  browserPlatformAdapter: () => browserPlatformAdapter
190
212
  });
191
213
  import * as openpgp2 from "openpgp";
192
- var BrowserCryptoAdapter, BrowserPGPAdapter, BrowserHttpAdapter, BrowserPlatformAdapter, browserPlatformAdapter;
214
+ var BrowserCryptoAdapter, BrowserPGPAdapter, BrowserHttpAdapter, BrowserCacheAdapter, BrowserPlatformAdapter, browserPlatformAdapter;
193
215
  var init_browser = __esm({
194
216
  "src/platform/browser.ts"() {
195
217
  "use strict";
@@ -368,15 +390,60 @@ var init_browser = __esm({
368
390
  return fetch(url, options);
369
391
  }
370
392
  };
393
+ BrowserCacheAdapter = class {
394
+ prefix = "vana_cache_";
395
+ get(key) {
396
+ try {
397
+ if (typeof sessionStorage === "undefined") {
398
+ return null;
399
+ }
400
+ return sessionStorage.getItem(this.prefix + key);
401
+ } catch {
402
+ return null;
403
+ }
404
+ }
405
+ set(key, value) {
406
+ try {
407
+ if (typeof sessionStorage !== "undefined") {
408
+ sessionStorage.setItem(this.prefix + key, value);
409
+ }
410
+ } catch {
411
+ }
412
+ }
413
+ delete(key) {
414
+ try {
415
+ if (typeof sessionStorage !== "undefined") {
416
+ sessionStorage.removeItem(this.prefix + key);
417
+ }
418
+ } catch {
419
+ }
420
+ }
421
+ clear() {
422
+ try {
423
+ if (typeof sessionStorage === "undefined") {
424
+ return;
425
+ }
426
+ const keys = Object.keys(sessionStorage);
427
+ for (const key of keys) {
428
+ if (key.startsWith(this.prefix)) {
429
+ sessionStorage.removeItem(key);
430
+ }
431
+ }
432
+ } catch {
433
+ }
434
+ }
435
+ };
371
436
  BrowserPlatformAdapter = class {
372
437
  crypto;
373
438
  pgp;
374
439
  http;
440
+ cache;
375
441
  platform = "browser";
376
442
  constructor() {
377
443
  this.crypto = new BrowserCryptoAdapter();
378
444
  this.pgp = new BrowserPGPAdapter();
379
445
  this.http = new BrowserHttpAdapter();
446
+ this.cache = new BrowserCacheAdapter();
380
447
  }
381
448
  };
382
449
  browserPlatformAdapter = new BrowserPlatformAdapter();
@@ -602,15 +669,45 @@ var NodeHttpAdapter = class {
602
669
  throw new Error("No fetch implementation available in Node.js environment");
603
670
  }
604
671
  };
672
+ var NodeCacheAdapter = class {
673
+ cache = /* @__PURE__ */ new Map();
674
+ defaultTtl = 2 * 60 * 60 * 1e3;
675
+ // 2 hours in milliseconds
676
+ get(key) {
677
+ const entry = this.cache.get(key);
678
+ if (!entry) {
679
+ return null;
680
+ }
681
+ if (Date.now() > entry.expires) {
682
+ this.cache.delete(key);
683
+ return null;
684
+ }
685
+ return entry.value;
686
+ }
687
+ set(key, value) {
688
+ this.cache.set(key, {
689
+ value,
690
+ expires: Date.now() + this.defaultTtl
691
+ });
692
+ }
693
+ delete(key) {
694
+ this.cache.delete(key);
695
+ }
696
+ clear() {
697
+ this.cache.clear();
698
+ }
699
+ };
605
700
  var NodePlatformAdapter = class {
606
701
  crypto;
607
702
  pgp;
608
703
  http;
704
+ cache;
609
705
  platform = "node";
610
706
  constructor() {
611
707
  this.crypto = new NodeCryptoAdapter();
612
708
  this.pgp = new NodePGPAdapter();
613
709
  this.http = new NodeHttpAdapter();
710
+ this.cache = new NodeCacheAdapter();
614
711
  }
615
712
  };
616
713
  var nodePlatformAdapter = new NodePlatformAdapter();
@@ -1032,276 +1129,45 @@ var PermissionError = class extends VanaError {
1032
1129
  }
1033
1130
  };
1034
1131
 
1035
- // src/config/addresses.ts
1036
- var CONTRACTS = {
1037
- // Core Platform Contracts
1038
- DataPermissions: {
1039
- addresses: {
1040
- 14800: "0x31fb1D48f6B2265A4cAD516BC39E96a18fb7c8de",
1041
- 1480: "0x31fb1D48f6B2265A4cAD516BC39E96a18fb7c8de"
1042
- }
1043
- },
1044
- DataRegistry: {
1045
- addresses: {
1046
- 14800: "0x8C8788f98385F6ba1adD4234e551ABba0f82Cb7C",
1047
- 1480: "0x8C8788f98385F6ba1adD4234e551ABba0f82Cb7C"
1048
- }
1049
- },
1050
- TeePoolPhala: {
1051
- addresses: {
1052
- 14800: "0xE8EC6BD73b23Ad40E6B9a6f4bD343FAc411bD99A",
1053
- 1480: "0xE8EC6BD73b23Ad40E6B9a6f4bD343FAc411bD99A"
1054
- }
1055
- },
1056
- ComputeEngine: {
1057
- addresses: {
1058
- 14800: "0xb2BFe33FA420c45F1Cf1287542ad81ae935447bd",
1059
- 1480: "0xb2BFe33FA420c45F1Cf1287542ad81ae935447bd"
1060
- }
1061
- },
1062
- // Data Access Infrastructure
1063
- DataRefinerRegistry: {
1064
- addresses: {
1065
- 14800: "0x93c3EF89369fDcf08Be159D9DeF0F18AB6Be008c",
1066
- 1480: "0x93c3EF89369fDcf08Be159D9DeF0F18AB6Be008c"
1067
- }
1068
- },
1069
- QueryEngine: {
1070
- addresses: {
1071
- 14800: "0xd25Eb66EA2452cf3238A2eC6C1FD1B7F5B320490",
1072
- 1480: "0xd25Eb66EA2452cf3238A2eC6C1FD1B7F5B320490"
1073
- }
1074
- },
1075
- VanaTreasury: {
1076
- addresses: {
1077
- 14800: "0x94a1E56e555ac48d092f490fB10CDFaB434915eD",
1078
- 1480: "0x94a1E56e555ac48d092f490fB10CDFaB434915eD"
1079
- }
1080
- },
1081
- ComputeInstructionRegistry: {
1082
- addresses: {
1083
- 14800: "0x5786B12b4c6Ba2bFAF0e77Ed30Bf6d32805563A5",
1084
- 1480: "0x5786B12b4c6Ba2bFAF0e77Ed30Bf6d32805563A5"
1085
- }
1086
- },
1087
- // TEE Pool Variants
1088
- TeePoolEphemeralStandard: {
1089
- addresses: {
1090
- 14800: "0xe124bae846D5ec157f75Bd9e68ca87C4d2AB835A",
1091
- 1480: "0xe124bae846D5ec157f75Bd9e68ca87C4d2AB835A"
1092
- }
1093
- },
1094
- TeePoolPersistentStandard: {
1095
- addresses: {
1096
- 14800: "0xe8bB8d0629651Cf33e0845d743976Dc1f0971d76",
1097
- 1480: "0xe8bB8d0629651Cf33e0845d743976Dc1f0971d76"
1098
- }
1099
- },
1100
- TeePoolPersistentGpu: {
1101
- addresses: {
1102
- 14800: "0x1c346Cd74f8551f8fa13f3F4b6b8dAE22338E6a9",
1103
- 1480: "0x1c346Cd74f8551f8fa13f3F4b6b8dAE22338E6a9"
1104
- }
1105
- },
1106
- TeePoolDedicatedStandard: {
1107
- addresses: {
1108
- 14800: "0xf024b7ac5E8417416f53B41ecfa58C8e9396687d",
1109
- 1480: "0xf024b7ac5E8417416f53B41ecfa58C8e9396687d"
1110
- }
1111
- },
1112
- TeePoolDedicatedGpu: {
1113
- addresses: {
1114
- 14800: "0xB1686FA9620bBf851714d1cB47b8a4Bf4664644E",
1115
- 1480: "0xB1686FA9620bBf851714d1cB47b8a4Bf4664644E"
1116
- }
1117
- },
1118
- // DLP Reward System
1119
- VanaEpoch: {
1120
- addresses: {
1121
- 14800: "0x2063cFF0609D59bCCc196E20Eb58A8696a6b15A0",
1122
- 1480: "0x2063cFF0609D59bCCc196E20Eb58A8696a6b15A0"
1123
- }
1124
- },
1125
- DLPRegistry: {
1126
- addresses: {
1127
- 14800: "0x4D59880a924526d1dD33260552Ff4328b1E18a43",
1128
- 1480: "0x4D59880a924526d1dD33260552Ff4328b1E18a43"
1129
- }
1130
- },
1131
- DLPRegistryTreasury: {
1132
- addresses: {
1133
- 14800: "0xb12ce1d27bEeFe39b6F0110b1AB77C21Aa0c9F9a",
1134
- 1480: "0xb12ce1d27bEeFe39b6F0110b1AB77C21Aa0c9F9a"
1135
- }
1136
- },
1137
- DLPPerformance: {
1138
- addresses: {
1139
- 14800: "0x847715C7DB37cF286611182Be0bD333cbfa29cc1",
1140
- 1480: "0x847715C7DB37cF286611182Be0bD333cbfa29cc1"
1141
- }
1142
- },
1143
- DLPRewardDeployer: {
1144
- addresses: {
1145
- 14800: "0xEFD0F9Ba9De70586b7c4189971cF754adC923B04",
1146
- 1480: "0xEFD0F9Ba9De70586b7c4189971cF754adC923B04"
1147
- }
1148
- },
1149
- DLPRewardDeployerTreasury: {
1150
- addresses: {
1151
- 14800: "0xb547ca8Fe4990fe330FeAeb1C2EBb42F925Af5b8",
1152
- 1480: "0xb547ca8Fe4990fe330FeAeb1C2EBb42F925Af5b8"
1153
- }
1154
- },
1155
- DLPRewardSwap: {
1156
- addresses: {
1157
- 14800: "0x7c6862C46830F0fc3bF3FF509EA1bD0EE7267fB0",
1158
- 1480: "0x7c6862C46830F0fc3bF3FF509EA1bD0EE7267fB0"
1159
- }
1160
- },
1161
- SwapHelper: {
1162
- addresses: {
1163
- 14800: "0x55D5e6F73326315bF2E091e97F04f0770e5C54e2",
1164
- 1480: "0x55D5e6F73326315bF2E091e97F04f0770e5C54e2"
1165
- }
1166
- },
1167
- // VanaPool (Staking)
1168
- VanaPoolStaking: {
1169
- addresses: {
1170
- 14800: "0x641C18E2F286c86f96CE95C8ec1EB9fC0415Ca0e",
1171
- 1480: "0x641C18E2F286c86f96CE95C8ec1EB9fC0415Ca0e"
1172
- }
1173
- },
1174
- VanaPoolEntity: {
1175
- addresses: {
1176
- 14800: "0x44f20490A82e1f1F1cC25Dd3BA8647034eDdce30",
1177
- 1480: "0x44f20490A82e1f1F1cC25Dd3BA8647034eDdce30"
1178
- }
1179
- },
1180
- VanaPoolTreasury: {
1181
- addresses: {
1182
- 14800: "0x143BE72CF2541604A7691933CAccd6D9cC17c003",
1183
- 1480: "0x143BE72CF2541604A7691933CAccd6D9cC17c003"
1184
- }
1185
- },
1186
- // DLP Deployment Contracts
1187
- DAT: {
1188
- addresses: {
1189
- 14800: "0xA706b93ccED89f13340673889e29F0a5cd84212d",
1190
- 1480: "0xA706b93ccED89f13340673889e29F0a5cd84212d"
1191
- }
1192
- },
1193
- DATFactory: {
1194
- addresses: {
1195
- 14800: "0x40f8bccF35a75ecef63BC3B1B3E06ffEB9220644",
1196
- 1480: "0x40f8bccF35a75ecef63BC3B1B3E06ffEB9220644"
1197
- }
1198
- },
1199
- DATPausable: {
1200
- addresses: {
1201
- 14800: "0xe69FE86f0B95cC2f8416Fe22815c85DC8887e76e",
1202
- 1480: "0xe69FE86f0B95cC2f8416Fe22815c85DC8887e76e"
1203
- }
1204
- },
1205
- DATVotes: {
1206
- addresses: {
1207
- 14800: "0xaE04c8A77E9B27869eb563720524A9aE0baf1831",
1208
- 1480: "0xaE04c8A77E9B27869eb563720524A9aE0baf1831"
1209
- }
1210
- },
1211
- // Utility Contracts (no ABIs in SDK)
1212
- Multicall3: {
1213
- addresses: {
1214
- 14800: "0xD8d2dFca27E8797fd779F8547166A2d3B29d360E",
1215
- 1480: "0xD8d2dFca27E8797fd779F8547166A2d3B29d360E"
1216
- }
1217
- },
1218
- Multisend: {
1219
- addresses: {
1220
- 14800: "0x8807e8BCDFbaA8c2761760f3FBA37F6f7F2C5b2d",
1221
- 1480: "0x8807e8BCDFbaA8c2761760f3FBA37F6f7F2C5b2d"
1222
- }
1223
- }
1224
- };
1225
- var LEGACY_CONTRACTS = {
1226
- // DEPRECATED: Original Intel SGX TeePool (PRO-347)
1227
- TeePool: {
1228
- addresses: {
1229
- 14800: "0x3c92fD91639b41f13338CE62f19131e7d19eaa0D",
1230
- 1480: "0x3c92fD91639b41f13338CE62f19131e7d19eaa0D"
1231
- }
1232
- },
1233
- // DEPRECATED: DLPRoot system (replaced by VanaPool + DLPRewards)
1234
- DLPRootEpoch: {
1235
- addresses: {
1236
- 14800: "0xc3d176cF6BccFCB9225b53B87a95147218e1537F",
1237
- 1480: "0xc3d176cF6BccFCB9225b53B87a95147218e1537F"
1238
- }
1239
- },
1240
- DLPRootCore: {
1241
- addresses: {
1242
- 14800: "0x0aBa5e28228c323A67712101d61a54d4ff5720FD",
1243
- 1480: "0x0aBa5e28228c323A67712101d61a54d4ff5720FD"
1244
- }
1245
- },
1246
- DLPRoot: {
1247
- addresses: {
1248
- 14800: "0xff14346dF2B8Fd0c95BF34f1c92e49417b508AD5",
1249
- 1480: "0xff14346dF2B8Fd0c95BF34f1c92e49417b508AD5"
1250
- }
1251
- },
1252
- DLPRootMetrics: {
1253
- addresses: {
1254
- 14800: "0xbb532917B6407c060Afd9Cb7d53527eCb91d6662",
1255
- 1480: "0xbb532917B6407c060Afd9Cb7d53527eCb91d6662"
1256
- }
1257
- },
1258
- DLPRootStakesTreasury: {
1259
- addresses: {
1260
- 14800: "0x52c3260ED5C235fcA43524CF508e29c897318775",
1261
- 1480: "0x52c3260ED5C235fcA43524CF508e29c897318775"
1262
- }
1263
- },
1264
- DLPRootRewardsTreasury: {
1265
- addresses: {
1266
- 14800: "0xDBFb6B8b9E2eCAEbdE64d665cD553dB81e524479",
1267
- 1480: "0xDBFb6B8b9E2eCAEbdE64d665cD553dB81e524479"
1268
- }
1269
- }
1270
- };
1271
- var CONTRACT_ADDRESSES = {
1272
- 14800: Object.fromEntries(
1273
- Object.entries(CONTRACTS).map(([name, info]) => [name, info.addresses[14800]]).filter(([, addr]) => addr)
1274
- ),
1275
- 1480: Object.fromEntries(
1276
- Object.entries(CONTRACTS).map(([name, info]) => [name, info.addresses[1480]]).filter(([, addr]) => addr)
1277
- )
1278
- };
1279
- var UTILITY_ADDRESSES = {
1280
- 14800: {
1281
- Multicall3: CONTRACTS.Multicall3.addresses[14800],
1282
- Multisend: CONTRACTS.Multisend.addresses[14800]
1283
- },
1284
- 1480: {
1285
- Multicall3: CONTRACTS.Multicall3.addresses[1480],
1286
- Multisend: CONTRACTS.Multisend.addresses[1480]
1287
- }
1288
- };
1289
- var LEGACY_ADDRESSES = {
1290
- 14800: Object.fromEntries(
1291
- Object.entries(LEGACY_CONTRACTS).map(([name, info]) => [name, info.addresses[14800]]).filter(([, addr]) => addr)
1292
- ),
1293
- 1480: Object.fromEntries(
1294
- Object.entries(LEGACY_CONTRACTS).map(([name, info]) => [name, info.addresses[1480]]).filter(([, addr]) => addr)
1295
- )
1296
- };
1297
- var getContractAddress = (chainId, contract) => {
1298
- const contractAddress = CONTRACT_ADDRESSES[chainId]?.[contract];
1299
- if (!contractAddress) {
1300
- throw new Error(
1301
- `Contract address not found for ${contract} on chain ${chainId}`
1302
- );
1132
+ // src/utils/transactionParsing.ts
1133
+ import { parseEventLogs } from "viem";
1134
+
1135
+ // src/config/eventMappings.ts
1136
+ var EVENT_MAPPINGS = {
1137
+ // Permission operations
1138
+ grant: {
1139
+ contract: "DataPermissions",
1140
+ event: "PermissionAdded"
1141
+ },
1142
+ revoke: {
1143
+ contract: "DataPermissions",
1144
+ event: "PermissionRevoked"
1145
+ },
1146
+ trustServer: {
1147
+ contract: "DataPermissions",
1148
+ event: "ServerTrusted"
1149
+ },
1150
+ untrustServer: {
1151
+ contract: "DataPermissions",
1152
+ event: "ServerUntrusted"
1153
+ },
1154
+ // Data registry operations
1155
+ addFile: {
1156
+ contract: "DataRegistry",
1157
+ event: "FileAdded"
1158
+ },
1159
+ addRefinement: {
1160
+ contract: "DataRegistry",
1161
+ event: "RefinementAdded"
1162
+ },
1163
+ updateRefinement: {
1164
+ contract: "DataRegistry",
1165
+ event: "RefinementUpdated"
1166
+ },
1167
+ addFilePermission: {
1168
+ contract: "DataRegistry",
1169
+ event: "PermissionGranted"
1303
1170
  }
1304
- return contractAddress;
1305
1171
  };
1306
1172
 
1307
1173
  // src/abi/ComputeEngineImplementation.ts
@@ -33508,6 +33374,332 @@ function getAbi(contract) {
33508
33374
  return abi;
33509
33375
  }
33510
33376
 
33377
+ // src/utils/transactionParsing.ts
33378
+ async function parseTransactionResult(context, hash, operation) {
33379
+ const mapping = EVENT_MAPPINGS[operation];
33380
+ try {
33381
+ console.debug(`\u{1F50D} Parsing ${operation} transaction: ${hash}`);
33382
+ const receipt = await context.publicClient.waitForTransactionReceipt({
33383
+ hash,
33384
+ timeout: 3e4
33385
+ // 30 second timeout
33386
+ });
33387
+ console.debug(`\u2705 Transaction confirmed in block ${receipt.blockNumber}`);
33388
+ const abi = getAbi(mapping.contract);
33389
+ const events = parseEventLogs({
33390
+ logs: receipt.logs,
33391
+ abi,
33392
+ eventName: mapping.event,
33393
+ strict: true
33394
+ // Only return logs that conform to the ABI
33395
+ });
33396
+ if (events.length === 0) {
33397
+ throw new BlockchainError(
33398
+ `No ${mapping.event} event found in transaction ${hash}. Transaction may have failed or reverted.`
33399
+ );
33400
+ }
33401
+ if (events.length > 1) {
33402
+ console.warn(
33403
+ `\u26A0\uFE0F Multiple ${mapping.event} events found in transaction ${hash}. Using the first one.`
33404
+ );
33405
+ }
33406
+ const event = events[0];
33407
+ console.debug(`\u{1F389} Found ${mapping.event} event with args:`, event.args);
33408
+ return {
33409
+ ...event.args,
33410
+ transactionHash: hash,
33411
+ blockNumber: receipt.blockNumber,
33412
+ gasUsed: receipt.gasUsed
33413
+ };
33414
+ } catch (error) {
33415
+ if (error instanceof BlockchainError || error instanceof NetworkError) {
33416
+ throw error;
33417
+ }
33418
+ if (error instanceof Error && error.message.includes("timeout")) {
33419
+ throw new NetworkError(
33420
+ `Transaction ${hash} confirmation timeout after 30 seconds. The transaction may still be pending.`,
33421
+ error
33422
+ );
33423
+ }
33424
+ throw new BlockchainError(
33425
+ `Failed to parse ${operation} transaction ${hash}: ${error instanceof Error ? error.message : "Unknown error"}`,
33426
+ error
33427
+ );
33428
+ }
33429
+ }
33430
+
33431
+ // src/config/addresses.ts
33432
+ var CONTRACTS = {
33433
+ // Core Platform Contracts
33434
+ DataPermissions: {
33435
+ addresses: {
33436
+ 14800: "0x31fb1D48f6B2265A4cAD516BC39E96a18fb7c8de",
33437
+ 1480: "0x31fb1D48f6B2265A4cAD516BC39E96a18fb7c8de"
33438
+ }
33439
+ },
33440
+ DataRegistry: {
33441
+ addresses: {
33442
+ 14800: "0x8C8788f98385F6ba1adD4234e551ABba0f82Cb7C",
33443
+ 1480: "0x8C8788f98385F6ba1adD4234e551ABba0f82Cb7C"
33444
+ }
33445
+ },
33446
+ TeePoolPhala: {
33447
+ addresses: {
33448
+ 14800: "0xE8EC6BD73b23Ad40E6B9a6f4bD343FAc411bD99A",
33449
+ 1480: "0xE8EC6BD73b23Ad40E6B9a6f4bD343FAc411bD99A"
33450
+ }
33451
+ },
33452
+ ComputeEngine: {
33453
+ addresses: {
33454
+ 14800: "0xb2BFe33FA420c45F1Cf1287542ad81ae935447bd",
33455
+ 1480: "0xb2BFe33FA420c45F1Cf1287542ad81ae935447bd"
33456
+ }
33457
+ },
33458
+ // Data Access Infrastructure
33459
+ DataRefinerRegistry: {
33460
+ addresses: {
33461
+ 14800: "0x93c3EF89369fDcf08Be159D9DeF0F18AB6Be008c",
33462
+ 1480: "0x93c3EF89369fDcf08Be159D9DeF0F18AB6Be008c"
33463
+ }
33464
+ },
33465
+ QueryEngine: {
33466
+ addresses: {
33467
+ 14800: "0xd25Eb66EA2452cf3238A2eC6C1FD1B7F5B320490",
33468
+ 1480: "0xd25Eb66EA2452cf3238A2eC6C1FD1B7F5B320490"
33469
+ }
33470
+ },
33471
+ VanaTreasury: {
33472
+ addresses: {
33473
+ 14800: "0x94a1E56e555ac48d092f490fB10CDFaB434915eD",
33474
+ 1480: "0x94a1E56e555ac48d092f490fB10CDFaB434915eD"
33475
+ }
33476
+ },
33477
+ ComputeInstructionRegistry: {
33478
+ addresses: {
33479
+ 14800: "0x5786B12b4c6Ba2bFAF0e77Ed30Bf6d32805563A5",
33480
+ 1480: "0x5786B12b4c6Ba2bFAF0e77Ed30Bf6d32805563A5"
33481
+ }
33482
+ },
33483
+ // TEE Pool Variants
33484
+ TeePoolEphemeralStandard: {
33485
+ addresses: {
33486
+ 14800: "0xe124bae846D5ec157f75Bd9e68ca87C4d2AB835A",
33487
+ 1480: "0xe124bae846D5ec157f75Bd9e68ca87C4d2AB835A"
33488
+ }
33489
+ },
33490
+ TeePoolPersistentStandard: {
33491
+ addresses: {
33492
+ 14800: "0xe8bB8d0629651Cf33e0845d743976Dc1f0971d76",
33493
+ 1480: "0xe8bB8d0629651Cf33e0845d743976Dc1f0971d76"
33494
+ }
33495
+ },
33496
+ TeePoolPersistentGpu: {
33497
+ addresses: {
33498
+ 14800: "0x1c346Cd74f8551f8fa13f3F4b6b8dAE22338E6a9",
33499
+ 1480: "0x1c346Cd74f8551f8fa13f3F4b6b8dAE22338E6a9"
33500
+ }
33501
+ },
33502
+ TeePoolDedicatedStandard: {
33503
+ addresses: {
33504
+ 14800: "0xf024b7ac5E8417416f53B41ecfa58C8e9396687d",
33505
+ 1480: "0xf024b7ac5E8417416f53B41ecfa58C8e9396687d"
33506
+ }
33507
+ },
33508
+ TeePoolDedicatedGpu: {
33509
+ addresses: {
33510
+ 14800: "0xB1686FA9620bBf851714d1cB47b8a4Bf4664644E",
33511
+ 1480: "0xB1686FA9620bBf851714d1cB47b8a4Bf4664644E"
33512
+ }
33513
+ },
33514
+ // DLP Reward System
33515
+ VanaEpoch: {
33516
+ addresses: {
33517
+ 14800: "0x2063cFF0609D59bCCc196E20Eb58A8696a6b15A0",
33518
+ 1480: "0x2063cFF0609D59bCCc196E20Eb58A8696a6b15A0"
33519
+ }
33520
+ },
33521
+ DLPRegistry: {
33522
+ addresses: {
33523
+ 14800: "0x4D59880a924526d1dD33260552Ff4328b1E18a43",
33524
+ 1480: "0x4D59880a924526d1dD33260552Ff4328b1E18a43"
33525
+ }
33526
+ },
33527
+ DLPRegistryTreasury: {
33528
+ addresses: {
33529
+ 14800: "0xb12ce1d27bEeFe39b6F0110b1AB77C21Aa0c9F9a",
33530
+ 1480: "0xb12ce1d27bEeFe39b6F0110b1AB77C21Aa0c9F9a"
33531
+ }
33532
+ },
33533
+ DLPPerformance: {
33534
+ addresses: {
33535
+ 14800: "0x847715C7DB37cF286611182Be0bD333cbfa29cc1",
33536
+ 1480: "0x847715C7DB37cF286611182Be0bD333cbfa29cc1"
33537
+ }
33538
+ },
33539
+ DLPRewardDeployer: {
33540
+ addresses: {
33541
+ 14800: "0xEFD0F9Ba9De70586b7c4189971cF754adC923B04",
33542
+ 1480: "0xEFD0F9Ba9De70586b7c4189971cF754adC923B04"
33543
+ }
33544
+ },
33545
+ DLPRewardDeployerTreasury: {
33546
+ addresses: {
33547
+ 14800: "0xb547ca8Fe4990fe330FeAeb1C2EBb42F925Af5b8",
33548
+ 1480: "0xb547ca8Fe4990fe330FeAeb1C2EBb42F925Af5b8"
33549
+ }
33550
+ },
33551
+ DLPRewardSwap: {
33552
+ addresses: {
33553
+ 14800: "0x7c6862C46830F0fc3bF3FF509EA1bD0EE7267fB0",
33554
+ 1480: "0x7c6862C46830F0fc3bF3FF509EA1bD0EE7267fB0"
33555
+ }
33556
+ },
33557
+ SwapHelper: {
33558
+ addresses: {
33559
+ 14800: "0x55D5e6F73326315bF2E091e97F04f0770e5C54e2",
33560
+ 1480: "0x55D5e6F73326315bF2E091e97F04f0770e5C54e2"
33561
+ }
33562
+ },
33563
+ // VanaPool (Staking)
33564
+ VanaPoolStaking: {
33565
+ addresses: {
33566
+ 14800: "0x641C18E2F286c86f96CE95C8ec1EB9fC0415Ca0e",
33567
+ 1480: "0x641C18E2F286c86f96CE95C8ec1EB9fC0415Ca0e"
33568
+ }
33569
+ },
33570
+ VanaPoolEntity: {
33571
+ addresses: {
33572
+ 14800: "0x44f20490A82e1f1F1cC25Dd3BA8647034eDdce30",
33573
+ 1480: "0x44f20490A82e1f1F1cC25Dd3BA8647034eDdce30"
33574
+ }
33575
+ },
33576
+ VanaPoolTreasury: {
33577
+ addresses: {
33578
+ 14800: "0x143BE72CF2541604A7691933CAccd6D9cC17c003",
33579
+ 1480: "0x143BE72CF2541604A7691933CAccd6D9cC17c003"
33580
+ }
33581
+ },
33582
+ // DLP Deployment Contracts
33583
+ DAT: {
33584
+ addresses: {
33585
+ 14800: "0xA706b93ccED89f13340673889e29F0a5cd84212d",
33586
+ 1480: "0xA706b93ccED89f13340673889e29F0a5cd84212d"
33587
+ }
33588
+ },
33589
+ DATFactory: {
33590
+ addresses: {
33591
+ 14800: "0x40f8bccF35a75ecef63BC3B1B3E06ffEB9220644",
33592
+ 1480: "0x40f8bccF35a75ecef63BC3B1B3E06ffEB9220644"
33593
+ }
33594
+ },
33595
+ DATPausable: {
33596
+ addresses: {
33597
+ 14800: "0xe69FE86f0B95cC2f8416Fe22815c85DC8887e76e",
33598
+ 1480: "0xe69FE86f0B95cC2f8416Fe22815c85DC8887e76e"
33599
+ }
33600
+ },
33601
+ DATVotes: {
33602
+ addresses: {
33603
+ 14800: "0xaE04c8A77E9B27869eb563720524A9aE0baf1831",
33604
+ 1480: "0xaE04c8A77E9B27869eb563720524A9aE0baf1831"
33605
+ }
33606
+ },
33607
+ // Utility Contracts (no ABIs in SDK)
33608
+ Multicall3: {
33609
+ addresses: {
33610
+ 14800: "0xD8d2dFca27E8797fd779F8547166A2d3B29d360E",
33611
+ 1480: "0xD8d2dFca27E8797fd779F8547166A2d3B29d360E"
33612
+ }
33613
+ },
33614
+ Multisend: {
33615
+ addresses: {
33616
+ 14800: "0x8807e8BCDFbaA8c2761760f3FBA37F6f7F2C5b2d",
33617
+ 1480: "0x8807e8BCDFbaA8c2761760f3FBA37F6f7F2C5b2d"
33618
+ }
33619
+ }
33620
+ };
33621
+ var LEGACY_CONTRACTS = {
33622
+ // DEPRECATED: Original Intel SGX TeePool (PRO-347)
33623
+ TeePool: {
33624
+ addresses: {
33625
+ 14800: "0x3c92fD91639b41f13338CE62f19131e7d19eaa0D",
33626
+ 1480: "0x3c92fD91639b41f13338CE62f19131e7d19eaa0D"
33627
+ }
33628
+ },
33629
+ // DEPRECATED: DLPRoot system (replaced by VanaPool + DLPRewards)
33630
+ DLPRootEpoch: {
33631
+ addresses: {
33632
+ 14800: "0xc3d176cF6BccFCB9225b53B87a95147218e1537F",
33633
+ 1480: "0xc3d176cF6BccFCB9225b53B87a95147218e1537F"
33634
+ }
33635
+ },
33636
+ DLPRootCore: {
33637
+ addresses: {
33638
+ 14800: "0x0aBa5e28228c323A67712101d61a54d4ff5720FD",
33639
+ 1480: "0x0aBa5e28228c323A67712101d61a54d4ff5720FD"
33640
+ }
33641
+ },
33642
+ DLPRoot: {
33643
+ addresses: {
33644
+ 14800: "0xff14346dF2B8Fd0c95BF34f1c92e49417b508AD5",
33645
+ 1480: "0xff14346dF2B8Fd0c95BF34f1c92e49417b508AD5"
33646
+ }
33647
+ },
33648
+ DLPRootMetrics: {
33649
+ addresses: {
33650
+ 14800: "0xbb532917B6407c060Afd9Cb7d53527eCb91d6662",
33651
+ 1480: "0xbb532917B6407c060Afd9Cb7d53527eCb91d6662"
33652
+ }
33653
+ },
33654
+ DLPRootStakesTreasury: {
33655
+ addresses: {
33656
+ 14800: "0x52c3260ED5C235fcA43524CF508e29c897318775",
33657
+ 1480: "0x52c3260ED5C235fcA43524CF508e29c897318775"
33658
+ }
33659
+ },
33660
+ DLPRootRewardsTreasury: {
33661
+ addresses: {
33662
+ 14800: "0xDBFb6B8b9E2eCAEbdE64d665cD553dB81e524479",
33663
+ 1480: "0xDBFb6B8b9E2eCAEbdE64d665cD553dB81e524479"
33664
+ }
33665
+ }
33666
+ };
33667
+ var CONTRACT_ADDRESSES = {
33668
+ 14800: Object.fromEntries(
33669
+ Object.entries(CONTRACTS).map(([name, info]) => [name, info.addresses[14800]]).filter(([, addr]) => addr)
33670
+ ),
33671
+ 1480: Object.fromEntries(
33672
+ Object.entries(CONTRACTS).map(([name, info]) => [name, info.addresses[1480]]).filter(([, addr]) => addr)
33673
+ )
33674
+ };
33675
+ var UTILITY_ADDRESSES = {
33676
+ 14800: {
33677
+ Multicall3: CONTRACTS.Multicall3.addresses[14800],
33678
+ Multisend: CONTRACTS.Multisend.addresses[14800]
33679
+ },
33680
+ 1480: {
33681
+ Multicall3: CONTRACTS.Multicall3.addresses[1480],
33682
+ Multisend: CONTRACTS.Multisend.addresses[1480]
33683
+ }
33684
+ };
33685
+ var LEGACY_ADDRESSES = {
33686
+ 14800: Object.fromEntries(
33687
+ Object.entries(LEGACY_CONTRACTS).map(([name, info]) => [name, info.addresses[14800]]).filter(([, addr]) => addr)
33688
+ ),
33689
+ 1480: Object.fromEntries(
33690
+ Object.entries(LEGACY_CONTRACTS).map(([name, info]) => [name, info.addresses[1480]]).filter(([, addr]) => addr)
33691
+ )
33692
+ };
33693
+ var getContractAddress = (chainId, contract) => {
33694
+ const contractAddress = CONTRACT_ADDRESSES[chainId]?.[contract];
33695
+ if (!contractAddress) {
33696
+ throw new Error(
33697
+ `Contract address not found for ${contract} on chain ${chainId}`
33698
+ );
33699
+ }
33700
+ return contractAddress;
33701
+ };
33702
+
33511
33703
  // src/utils/grantFiles.ts
33512
33704
  import { keccak256, toHex } from "viem";
33513
33705
  function createGrantFile(params) {
@@ -33909,6 +34101,158 @@ function validateOperationAccess(grantFile, requestedOperation) {
33909
34101
  }
33910
34102
  }
33911
34103
 
34104
+ // src/utils/signatureCache.ts
34105
+ init_crypto_utils();
34106
+ var SignatureCache = class {
34107
+ static PREFIX = "vana_sig_";
34108
+ static DEFAULT_TTL_HOURS = 2;
34109
+ /**
34110
+ * Get a cached signature if it exists and hasn't expired
34111
+ *
34112
+ * @param cache - Platform cache adapter instance
34113
+ * @param walletAddress - Wallet address that created the signature
34114
+ * @param messageHash - Hash of the message that was signed
34115
+ * @returns The cached signature if valid, null if expired or not found
34116
+ * @example
34117
+ * ```typescript
34118
+ * const messageHash = SignatureCache.hashMessage(typedData);
34119
+ * const cached = SignatureCache.get(cache, '0x123...', messageHash);
34120
+ * if (cached) {
34121
+ * console.log('Using cached signature:', cached);
34122
+ * }
34123
+ * ```
34124
+ */
34125
+ static get(cache, walletAddress, messageHash) {
34126
+ const key = this.getCacheKey(walletAddress, messageHash);
34127
+ try {
34128
+ const stored = cache.get(key);
34129
+ if (!stored) return null;
34130
+ const cached = JSON.parse(stored);
34131
+ if (Date.now() > cached.expires) {
34132
+ cache.delete(key);
34133
+ return null;
34134
+ }
34135
+ return cached.signature;
34136
+ } catch {
34137
+ try {
34138
+ cache.delete(key);
34139
+ } catch {
34140
+ }
34141
+ return null;
34142
+ }
34143
+ }
34144
+ /**
34145
+ * Store a signature in the cache with configurable TTL
34146
+ *
34147
+ * @param cache - Platform cache adapter instance
34148
+ * @param walletAddress - Wallet address that created the signature
34149
+ * @param messageHash - Hash of the message that was signed
34150
+ * @param signature - The signature to cache
34151
+ * @param ttlHours - Time to live in hours (default: 2)
34152
+ * @example
34153
+ * ```typescript
34154
+ * const signature = await wallet.signTypedData(typedData);
34155
+ * const messageHash = SignatureCache.hashMessage(typedData);
34156
+ *
34157
+ * // Cache for default 2 hours
34158
+ * SignatureCache.set(cache, walletAddress, messageHash, signature);
34159
+ *
34160
+ * // Cache for 24 hours
34161
+ * SignatureCache.set(cache, walletAddress, messageHash, signature, 24);
34162
+ * ```
34163
+ */
34164
+ static set(cache, walletAddress, messageHash, signature, ttlHours = this.DEFAULT_TTL_HOURS) {
34165
+ const key = this.getCacheKey(walletAddress, messageHash);
34166
+ const cached = {
34167
+ signature,
34168
+ expires: Date.now() + ttlHours * 36e5
34169
+ // Convert hours to milliseconds
34170
+ };
34171
+ try {
34172
+ cache.set(key, JSON.stringify(cached));
34173
+ } catch {
34174
+ }
34175
+ }
34176
+ /**
34177
+ * Clear all cached signatures (useful for testing or explicit cleanup)
34178
+ *
34179
+ * @param cache - Platform cache adapter instance
34180
+ * @example
34181
+ * ```typescript
34182
+ * // Clear all signatures when user logs out
34183
+ * SignatureCache.clear(cache);
34184
+ *
34185
+ * // Clear before running tests
34186
+ * beforeEach(() => {
34187
+ * SignatureCache.clear(cache);
34188
+ * });
34189
+ * ```
34190
+ */
34191
+ static clear(cache) {
34192
+ try {
34193
+ cache.clear();
34194
+ } catch {
34195
+ }
34196
+ }
34197
+ static getCacheKey(walletAddress, messageHash) {
34198
+ return `${this.PREFIX}${walletAddress.toLowerCase()}:${messageHash}`;
34199
+ }
34200
+ /**
34201
+ * Generate a deterministic hash of a message object for cache key generation
34202
+ *
34203
+ * @remarks
34204
+ * Creates a consistent hash from complex objects including EIP-712 typed data.
34205
+ * Handles BigInt serialization and produces a 32-character hash that balances
34206
+ * uniqueness with key length constraints.
34207
+ *
34208
+ * @param message - The message object to hash (typically EIP-712 typed data)
34209
+ * @returns A 32-character hash string suitable for cache keys
34210
+ * @example
34211
+ * ```typescript
34212
+ * const typedData = {
34213
+ * domain: { name: 'Vana', version: '1' },
34214
+ * message: { nonce: 123n, grant: '...' }
34215
+ * };
34216
+ *
34217
+ * const hash = SignatureCache.hashMessage(typedData);
34218
+ * // Returns something like: "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
34219
+ * ```
34220
+ */
34221
+ static hashMessage(message) {
34222
+ const jsonString = JSON.stringify(message, this.bigIntReplacer);
34223
+ const base64Hash = toBase64(jsonString);
34224
+ const cleaned = base64Hash.replace(/[^a-zA-Z0-9]/g, "");
34225
+ if (cleaned.length > 32) {
34226
+ return cleaned.substring(0, 16) + cleaned.substring(cleaned.length - 16);
34227
+ }
34228
+ return cleaned.substring(0, 32);
34229
+ }
34230
+ /**
34231
+ * Custom JSON replacer that converts BigInt values to strings for serialization
34232
+ * This ensures deterministic cache key generation for EIP-712 typed data
34233
+ *
34234
+ * @param _key - The object key being serialized (unused)
34235
+ * @param value - The value to serialize
34236
+ * @returns The serialized value
34237
+ */
34238
+ static bigIntReplacer(_key, value) {
34239
+ if (typeof value === "bigint") {
34240
+ return `__BIGINT__${value.toString()}`;
34241
+ }
34242
+ return value;
34243
+ }
34244
+ };
34245
+ async function withSignatureCache(cache, walletAddress, typedData, signFn, ttlHours) {
34246
+ const messageHash = SignatureCache.hashMessage(typedData);
34247
+ const cached = SignatureCache.get(cache, walletAddress, messageHash);
34248
+ if (cached) {
34249
+ return cached;
34250
+ }
34251
+ const signature = await signFn();
34252
+ SignatureCache.set(cache, walletAddress, messageHash, signature, ttlHours);
34253
+ return signature;
34254
+ }
34255
+
33912
34256
  // src/controllers/permissions.ts
33913
34257
  var PermissionsController = class {
33914
34258
  constructor(context) {
@@ -33917,21 +34261,21 @@ var PermissionsController = class {
33917
34261
  /**
33918
34262
  * Grants permission for an application to access user data with gasless transactions.
33919
34263
  *
33920
- * @remarks
33921
- * This method combines signature creation and gasless submission for a complete
33922
- * end-to-end permission grant flow. It creates the grant file, stores it on IPFS,
33923
- * generates an EIP-712 signature, and submits via relayer. The grant file contains
33924
- * detailed parameters while the blockchain stores only a reference to enable
33925
- * efficient permission queries.
34264
+ * This method provides a complete end-to-end permission grant flow that returns
34265
+ * the permission ID and other relevant data immediately after successful submission.
34266
+ * For advanced users who need more control over the transaction lifecycle, use
34267
+ * `submitPermissionGrant()` instead.
34268
+ *
33926
34269
  * @param params - The permission grant configuration object
33927
- * @returns A Promise that resolves to the transaction hash when successfully submitted
34270
+ * @returns Promise resolving to permission data from the PermissionAdded event
33928
34271
  * @throws {RelayerError} When gasless transaction submission fails
33929
34272
  * @throws {SignatureError} When user rejects the signature request
33930
34273
  * @throws {SerializationError} When grant data cannot be serialized
33931
- * @throws {BlockchainError} When permission grant preparation fails
34274
+ * @throws {BlockchainError} When permission grant fails or event parsing fails
34275
+ * @throws {NetworkError} When transaction confirmation times out
33932
34276
  * @example
33933
34277
  * ```typescript
33934
- * const txHash = await vana.permissions.grant({
34278
+ * const result = await vana.permissions.grant({
33935
34279
  * grantee: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36",
33936
34280
  * operation: "llm_inference",
33937
34281
  * parameters: {
@@ -33941,10 +34285,42 @@ var PermissionsController = class {
33941
34285
  * },
33942
34286
  * });
33943
34287
  *
33944
- * console.log(`Permission granted: ${txHash}`);
34288
+ * console.log(`Permission ${result.permissionId} granted to ${result.user}`);
34289
+ * console.log(`Transaction: ${result.transactionHash}`);
34290
+ *
34291
+ * // Can immediately use the permission ID for other operations
34292
+ * await vana.permissions.revoke({ permissionId: result.permissionId });
33945
34293
  * ```
33946
34294
  */
33947
34295
  async grant(params) {
34296
+ const txHash = await this.submitPermissionGrant(params);
34297
+ return parseTransactionResult(this.context, txHash, "grant");
34298
+ }
34299
+ /**
34300
+ * Submits a permission grant transaction and returns the transaction hash immediately.
34301
+ *
34302
+ * This is the lower-level method that provides maximum control over transaction timing.
34303
+ * Use this when you want to handle transaction confirmation and event parsing separately,
34304
+ * or when submitting multiple transactions in batch.
34305
+ *
34306
+ * @param params - The permission grant configuration object
34307
+ * @returns Promise that resolves to the transaction hash when successfully submitted
34308
+ * @throws {RelayerError} When gasless transaction submission fails
34309
+ * @throws {SignatureError} When user rejects the signature request
34310
+ * @throws {SerializationError} When grant data cannot be serialized
34311
+ * @throws {BlockchainError} When permission grant preparation fails
34312
+ * @example
34313
+ * ```typescript
34314
+ * // Submit transaction and handle confirmation later
34315
+ * const txHash = await vana.permissions.submitPermissionGrant(params);
34316
+ * console.log(`Transaction submitted: ${txHash}`);
34317
+ *
34318
+ * // Later, when you need the permission data:
34319
+ * const result = await parseTransactionResult(context, txHash, 'grant');
34320
+ * console.log(`Permission ID: ${result.permissionId}`);
34321
+ * ```
34322
+ */
34323
+ async submitPermissionGrant(params) {
33948
34324
  const { typedData, signature } = await this.createAndSign(params);
33949
34325
  return await this.submitSignedGrant(typedData, signature);
33950
34326
  }
@@ -33958,6 +34334,8 @@ var PermissionsController = class {
33958
34334
  * until the returned `confirm()` function is called.
33959
34335
  * @param params - The permission grant parameters
33960
34336
  * @returns A promise resolving to a preview object and confirm function
34337
+ * @throws {SerializationError} When grant parameters are invalid or cannot be serialized
34338
+ * @throws {BlockchainError} When grant validation fails or preparation encounters an error
33961
34339
  * @example
33962
34340
  * ```typescript
33963
34341
  * const { preview, confirm } = await vana.permissions.prepareGrant({
@@ -34362,22 +34740,51 @@ var PermissionsController = class {
34362
34740
  /**
34363
34741
  * Revokes a previously granted permission.
34364
34742
  *
34743
+ * This method provides complete revocation with automatic event parsing to confirm
34744
+ * the permission was successfully revoked. For advanced users who need more control,
34745
+ * use `submitPermissionRevoke()` instead.
34746
+ *
34365
34747
  * @param params - Parameters for revoking the permission
34366
- * @returns Promise resolving to transaction hash
34748
+ * @param params.permissionId - Permission identifier (accepts bigint, number, or string).
34749
+ * Obtain from permission grants via `getUserPermissionGrantsOnChain()`.
34750
+ * @returns Promise resolving to revocation data from PermissionRevoked event
34751
+ * @throws {BlockchainError} When revocation fails or event parsing fails
34752
+ * @throws {UserRejectedRequestError} When user rejects the transaction
34753
+ * @throws {NetworkError} When transaction confirmation times out
34367
34754
  * @example
34368
34755
  * ```typescript
34369
- * // Revoke a permission by its ID
34370
- * const txHash = await vana.permissions.revoke({
34756
+ * // Revoke a permission and get confirmation
34757
+ * const result = await vana.permissions.revoke({
34371
34758
  * permissionId: 123n
34372
34759
  * });
34373
- * console.log('Permission revoked in transaction:', txHash);
34374
- *
34375
- * // Wait for confirmation if needed
34376
- * const receipt = await vana.core.waitForTransaction(txHash);
34377
- * console.log('Revocation confirmed in block:', receipt.blockNumber);
34760
+ * console.log(`Permission ${result.permissionId} revoked in transaction ${result.transactionHash}`);
34761
+ * console.log(`Revoked in block ${result.blockNumber}`);
34378
34762
  * ```
34379
34763
  */
34380
34764
  async revoke(params) {
34765
+ const txHash = await this.submitPermissionRevoke(params);
34766
+ return parseTransactionResult(this.context, txHash, "revoke");
34767
+ }
34768
+ /**
34769
+ * Submits a permission revocation transaction and returns the transaction hash immediately.
34770
+ *
34771
+ * This is the lower-level method that provides maximum control over transaction timing.
34772
+ * Use this when you want to handle transaction confirmation and event parsing separately.
34773
+ *
34774
+ * @param params - Parameters for revoking the permission
34775
+ * @returns Promise resolving to the transaction hash when successfully submitted
34776
+ * @throws {BlockchainError} When revocation transaction fails
34777
+ * @throws {UserRejectedRequestError} When user rejects the transaction
34778
+ * @example
34779
+ * ```typescript
34780
+ * // Submit revocation and handle confirmation later
34781
+ * const txHash = await vana.permissions.submitPermissionRevoke({
34782
+ * permissionId: 123n
34783
+ * });
34784
+ * console.log(`Revocation submitted: ${txHash}`);
34785
+ * ```
34786
+ */
34787
+ async submitPermissionRevoke(params) {
34381
34788
  try {
34382
34789
  if (!this.context.walletClient.chain?.id) {
34383
34790
  throw new BlockchainError("Chain ID not available");
@@ -34415,6 +34822,11 @@ var PermissionsController = class {
34415
34822
  *
34416
34823
  * @param params - Parameters for revoking the permission
34417
34824
  * @returns Promise resolving to transaction hash
34825
+ * @throws {BlockchainError} When chain ID is not available
34826
+ * @throws {NonceError} When retrieving user nonce fails
34827
+ * @throws {SignatureError} When user rejects the signature request
34828
+ * @throws {RelayerError} When gasless submission fails
34829
+ * @throws {PermissionError} When revocation fails for any other reason
34418
34830
  */
34419
34831
  async revokeWithSignature(params) {
34420
34832
  try {
@@ -34457,6 +34869,9 @@ var PermissionsController = class {
34457
34869
  * Retrieves the user's current nonce from the DataPermissions contract.
34458
34870
  *
34459
34871
  * @returns Promise resolving to the user's current nonce value
34872
+ * @throws {Error} When wallet account is not available
34873
+ * @throws {Error} When chain ID is not available
34874
+ * @throws {NonceError} When reading nonce from contract fails
34460
34875
  */
34461
34876
  async getUserNonce() {
34462
34877
  try {
@@ -34543,17 +34958,24 @@ var PermissionsController = class {
34543
34958
  };
34544
34959
  }
34545
34960
  /**
34546
- * Signs typed data using the wallet client.
34961
+ * Signs typed data using the wallet client with signature caching.
34547
34962
  *
34548
34963
  * @param typedData - The EIP-712 typed data structure to sign
34549
34964
  * @returns Promise resolving to the cryptographic signature
34550
34965
  */
34551
34966
  async signTypedData(typedData) {
34552
34967
  try {
34553
- const signature = await this.context.walletClient.signTypedData(
34554
- typedData
34968
+ const walletAddress = this.context.walletClient.account?.address || await this.getUserAddress();
34969
+ return await withSignatureCache(
34970
+ this.context.platform.cache,
34971
+ walletAddress,
34972
+ typedData,
34973
+ async () => {
34974
+ return await this.context.walletClient.signTypedData(
34975
+ typedData
34976
+ );
34977
+ }
34555
34978
  );
34556
- return signature;
34557
34979
  } catch (error) {
34558
34980
  if (error instanceof Error && error.message.includes("rejected")) {
34559
34981
  throw new UserRejectedRequestError();
@@ -34696,6 +35118,7 @@ var PermissionsController = class {
34696
35118
  *
34697
35119
  * @param fileId - The file ID to query permissions for
34698
35120
  * @returns Promise resolving to array of permission IDs
35121
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
34699
35122
  */
34700
35123
  async getFilePermissionIds(fileId) {
34701
35124
  try {
@@ -34724,6 +35147,7 @@ var PermissionsController = class {
34724
35147
  *
34725
35148
  * @param permissionId - The permission ID to query files for
34726
35149
  * @returns Promise resolving to array of file IDs
35150
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
34727
35151
  */
34728
35152
  async getPermissionFileIds(permissionId) {
34729
35153
  try {
@@ -34752,6 +35176,7 @@ var PermissionsController = class {
34752
35176
  *
34753
35177
  * @param permissionId - The permission ID to check
34754
35178
  * @returns Promise resolving to boolean indicating if permission is active
35179
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
34755
35180
  */
34756
35181
  async isActivePermission(permissionId) {
34757
35182
  try {
@@ -34780,6 +35205,7 @@ var PermissionsController = class {
34780
35205
  *
34781
35206
  * @param permissionId - The permission ID to query
34782
35207
  * @returns Promise resolving to permission info
35208
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
34783
35209
  */
34784
35210
  async getPermissionInfo(permissionId) {
34785
35211
  try {
@@ -34827,13 +35253,18 @@ var PermissionsController = class {
34827
35253
  * Trusts a server for data processing.
34828
35254
  *
34829
35255
  * @param params - Parameters for trusting the server
35256
+ * @param params.serverId - The server's Ethereum address
35257
+ * @param params.serverUrl - The server's URL endpoint
34830
35258
  * @returns Promise resolving to transaction hash
35259
+ * @throws {UserRejectedRequestError} When user rejects the transaction
35260
+ * @throws {BlockchainError} When chain ID is unavailable or transaction fails
35261
+ * @throws {Error} When wallet account is not available
34831
35262
  * @example
34832
35263
  * ```typescript
34833
35264
  * // Trust a server by providing its ID and URL
34834
35265
  * const txHash = await vana.permissions.trustServer({
34835
35266
  * serverId: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
34836
- * serverUrl: 'https://myserver.example.com'
35267
+ * serverUrl: 'https://personal-server.vana.org'
34837
35268
  * });
34838
35269
  * console.log('Server trusted in transaction:', txHash);
34839
35270
  *
@@ -34874,6 +35305,12 @@ var PermissionsController = class {
34874
35305
  *
34875
35306
  * @param params - Parameters for trusting the server
34876
35307
  * @returns Promise resolving to transaction hash
35308
+ * @throws {BlockchainError} When chain ID is not available
35309
+ * @throws {NonceError} When retrieving user nonce fails
35310
+ * @throws {SignatureError} When user rejects the signature request
35311
+ * @throws {RelayerError} When gasless submission fails
35312
+ * @throws {ServerUrlMismatchError} When server URL doesn't match existing registration
35313
+ * @throws {BlockchainError} When trust operation fails for any other reason
34877
35314
  */
34878
35315
  async trustServerWithSignature(params) {
34879
35316
  try {
@@ -34948,7 +35385,12 @@ var PermissionsController = class {
34948
35385
  * Untrusts a server.
34949
35386
  *
34950
35387
  * @param params - Parameters for untrusting the server
35388
+ * @param params.serverId - The server's Ethereum address to untrust
34951
35389
  * @returns Promise resolving to transaction hash
35390
+ * @throws {Error} When wallet account is not available
35391
+ * @throws {NonceError} When retrieving user nonce fails
35392
+ * @throws {UserRejectedRequestError} When user rejects the transaction
35393
+ * @throws {BlockchainError} When untrust transaction fails
34952
35394
  */
34953
35395
  async untrustServer(params) {
34954
35396
  const nonce = await this.getUserNonce();
@@ -34962,7 +35404,13 @@ var PermissionsController = class {
34962
35404
  * Untrusts a server using a signature (gasless transaction).
34963
35405
  *
34964
35406
  * @param params - Parameters for untrusting the server
35407
+ * @param params.serverId - The server's Ethereum address to untrust
34965
35408
  * @returns Promise resolving to transaction hash
35409
+ * @throws {Error} When wallet account is not available
35410
+ * @throws {NonceError} When retrieving user nonce fails
35411
+ * @throws {SignatureError} When user rejects the signature request
35412
+ * @throws {RelayerError} When gasless submission fails
35413
+ * @throws {BlockchainError} When untrust transaction fails
34966
35414
  */
34967
35415
  async untrustServerWithSignature(params) {
34968
35416
  try {
@@ -35004,6 +35452,7 @@ var PermissionsController = class {
35004
35452
  *
35005
35453
  * @param userAddress - Optional user address (defaults to current user)
35006
35454
  * @returns Promise resolving to array of trusted server addresses
35455
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
35007
35456
  */
35008
35457
  async getTrustedServers(userAddress) {
35009
35458
  try {
@@ -35033,6 +35482,7 @@ var PermissionsController = class {
35033
35482
  *
35034
35483
  * @param serverId - Server address
35035
35484
  * @returns Promise resolving to server information
35485
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
35036
35486
  */
35037
35487
  async getServerInfo(serverId) {
35038
35488
  try {
@@ -35061,6 +35511,7 @@ var PermissionsController = class {
35061
35511
  *
35062
35512
  * @param userAddress - Optional user address (defaults to current user)
35063
35513
  * @returns Promise resolving to the number of trusted servers
35514
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
35064
35515
  */
35065
35516
  async getTrustedServersCount(userAddress) {
35066
35517
  try {
@@ -35090,6 +35541,7 @@ var PermissionsController = class {
35090
35541
  *
35091
35542
  * @param options - Query options including pagination parameters
35092
35543
  * @returns Promise resolving to paginated trusted servers
35544
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
35093
35545
  */
35094
35546
  async getTrustedServersPaginated(options = {}) {
35095
35547
  try {
@@ -35149,6 +35601,7 @@ var PermissionsController = class {
35149
35601
  *
35150
35602
  * @param options - Query options
35151
35603
  * @returns Promise resolving to array of trusted server info
35604
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
35152
35605
  */
35153
35606
  async getTrustedServersWithInfo(options = {}) {
35154
35607
  try {
@@ -35186,6 +35639,7 @@ var PermissionsController = class {
35186
35639
  *
35187
35640
  * @param serverIds - Array of server IDs to query
35188
35641
  * @returns Promise resolving to batch result with successes and failures
35642
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
35189
35643
  */
35190
35644
  async getServerInfoBatch(serverIds) {
35191
35645
  if (serverIds.length === 0) {
@@ -35387,15 +35841,22 @@ import { getContract, decodeEventLog } from "viem";
35387
35841
 
35388
35842
  // src/utils/encryption.ts
35389
35843
  var DEFAULT_ENCRYPTION_SEED = "Please sign to retrieve your encryption key";
35390
- async function generateEncryptionKey(wallet, seed = DEFAULT_ENCRYPTION_SEED) {
35844
+ async function generateEncryptionKey(wallet, platformAdapter, seed = DEFAULT_ENCRYPTION_SEED) {
35391
35845
  if (!wallet.account) {
35392
35846
  throw new Error("Wallet account is required for encryption key generation");
35393
35847
  }
35394
- const signature = await wallet.signMessage({
35395
- account: wallet.account,
35396
- message: seed
35397
- });
35398
- return signature;
35848
+ const messageData = { message: seed };
35849
+ return await withSignatureCache(
35850
+ platformAdapter.cache,
35851
+ wallet.account.address,
35852
+ messageData,
35853
+ async () => {
35854
+ return await wallet.signMessage({
35855
+ account: wallet.account,
35856
+ message: seed
35857
+ });
35858
+ }
35859
+ );
35399
35860
  }
35400
35861
  async function encryptWithWalletPublicKey(data, publicKey, platformAdapter) {
35401
35862
  try {
@@ -35560,6 +36021,7 @@ var DataController = class {
35560
36021
  if (encrypt3) {
35561
36022
  const encryptionKey = await generateEncryptionKey(
35562
36023
  this.context.walletClient,
36024
+ this.context.platform,
35563
36025
  DEFAULT_ENCRYPTION_SEED
35564
36026
  );
35565
36027
  finalBlob = await encryptBlobWithSignedKey(
@@ -35585,26 +36047,21 @@ var DataController = class {
35585
36047
  );
35586
36048
  const userAddress = owner || await this.getUserAddress();
35587
36049
  let encryptedPermissions = [];
35588
- if (permissions.length > 0 && encrypt3) {
36050
+ if (permissions.length > 0) {
35589
36051
  const userEncryptionKey = await generateEncryptionKey(
35590
36052
  this.context.walletClient,
36053
+ this.context.platform,
35591
36054
  DEFAULT_ENCRYPTION_SEED
35592
36055
  );
35593
36056
  encryptedPermissions = await Promise.all(
35594
36057
  permissions.map(async (permission) => {
35595
- const publicKey = permission.publicKey;
35596
- if (!publicKey) {
35597
- throw new Error(
35598
- `Public key required for permission to ${permission.grantee} when encryption is enabled`
35599
- );
35600
- }
35601
36058
  const encryptedKey = await encryptWithWalletPublicKey(
35602
36059
  userEncryptionKey,
35603
- publicKey,
36060
+ permission.publicKey,
35604
36061
  this.context.platform
35605
36062
  );
35606
36063
  return {
35607
- account: permission.grantee,
36064
+ account: permission.account,
35608
36065
  key: encryptedKey
35609
36066
  };
35610
36067
  })
@@ -35676,9 +36133,14 @@ var DataController = class {
35676
36133
  * @param file - The user file to decrypt (typically from getUserFiles)
35677
36134
  * @param encryptionSeed - Optional custom encryption seed (defaults to Vana standard)
35678
36135
  * @returns Promise resolving to the decrypted file content as a Blob
35679
- * @throws {Error} When the wallet is not connected
35680
- * @throws {Error} When fetching the encrypted content fails
35681
- * @throws {Error} When decryption fails (wrong key or corrupted data)
36136
+ * @throws {Error} "No addresses available in wallet client" - When wallet is not connected
36137
+ * @throws {Error} "Network error: Cannot access the file URL" - When file URL is inaccessible (CORS, server down)
36138
+ * @throws {Error} "File not found: The encrypted file is no longer available" - When file returns 404
36139
+ * @throws {Error} "Access denied" - When file returns 403 (no permission)
36140
+ * @throws {Error} "File is empty or could not be retrieved" - When file has no content
36141
+ * @throws {Error} "Invalid file format: This file doesn't appear to be encrypted with the Vana protocol" - When file is not properly encrypted
36142
+ * @throws {Error} "Wrong encryption key" - When decryption fails due to incorrect key/seed
36143
+ * @throws {Error} "Failed to decrypt file: {error}" - General decryption failures
35682
36144
  * @example
35683
36145
  * ```typescript
35684
36146
  * // Basic file decryption
@@ -35708,6 +36170,7 @@ var DataController = class {
35708
36170
  try {
35709
36171
  const encryptionKey = await generateEncryptionKey(
35710
36172
  this.context.walletClient,
36173
+ this.context.platform,
35711
36174
  encryptionSeed || DEFAULT_ENCRYPTION_SEED
35712
36175
  );
35713
36176
  let encryptedBlob;
@@ -35797,11 +36260,20 @@ var DataController = class {
35797
36260
  * This method queries the Vana subgraph to find files directly owned by the user.
35798
36261
  * It efficiently handles large datasets by using the File entity's owner field
35799
36262
  * and returns complete file metadata without additional contract calls.
36263
+ *
36264
+ * **Deduplication Behavior:**
36265
+ * The method automatically deduplicates files by ID, keeping only the latest version
36266
+ * (highest timestamp) when duplicate file IDs are found. This handles cases where
36267
+ * the subgraph may contain multiple entries for the same file due to re-indexing
36268
+ * or blockchain reorganizations.
35800
36269
  * @param params - The query parameters object
35801
36270
  * @param params.owner - The wallet address of the file owner to query
35802
36271
  * @param params.subgraphUrl - Optional subgraph URL to override the default endpoint
35803
- * @returns A Promise that resolves to an array of UserFile objects with metadata
35804
- * @throws {Error} When the subgraph is unavailable or returns invalid data
36272
+ * @returns A Promise that resolves to an array of UserFile objects with metadata, sorted by latest timestamp first
36273
+ * @throws {Error} When subgraphUrl is not provided and not configured - "subgraphUrl is required"
36274
+ * @throws {Error} When subgraph request fails - "Subgraph request failed: {status} {statusText}"
36275
+ * @throws {Error} When subgraph returns errors - "Subgraph errors: {error messages}"
36276
+ * @throws {Error} When JSON parsing fails - "Failed to fetch user files from subgraph: {error}"
35805
36277
  * @example
35806
36278
  * ```typescript
35807
36279
  * // Query files for a specific user
@@ -36304,6 +36776,9 @@ var DataController = class {
36304
36776
  *
36305
36777
  * @param fileId - The file ID to look up
36306
36778
  * @returns Promise resolving to UserFile object
36779
+ * @throws {Error} "Chain ID not available" - When wallet chain is not configured
36780
+ * @throws {Error} "File not found" - When file ID doesn't exist or returns empty data
36781
+ * @throws {Error} "Failed to fetch file {fileId}: {error}" - General contract read failures
36307
36782
  * @example
36308
36783
  * ```typescript
36309
36784
  * try {
@@ -36373,7 +36848,21 @@ var DataController = class {
36373
36848
  /**
36374
36849
  * Uploads an encrypted file to storage and registers it on the blockchain.
36375
36850
  *
36376
- * @deprecated Use vana.data.upload() instead for the high-level API with automatic encryption
36851
+ * @deprecated Since v2.0.0 - Use vana.data.upload() instead for the high-level API with automatic encryption
36852
+ *
36853
+ * Migration guide:
36854
+ * ```typescript
36855
+ * // Old way (deprecated):
36856
+ * const encrypted = await encryptBlob(data, key);
36857
+ * const result = await vana.data.uploadEncryptedFile(encrypted, filename);
36858
+ *
36859
+ * // New way:
36860
+ * const result = await vana.data.upload({
36861
+ * content: data,
36862
+ * filename: filename,
36863
+ * encrypt: true // Handles encryption automatically
36864
+ * });
36865
+ * ```
36377
36866
  * @param encryptedFile - The encrypted file blob to upload
36378
36867
  * @param filename - Optional filename for the upload
36379
36868
  * @param providerName - Optional storage provider to use
@@ -36461,7 +36950,22 @@ var DataController = class {
36461
36950
  /**
36462
36951
  * Uploads an encrypted file to storage and registers it on the blockchain with a schema.
36463
36952
  *
36464
- * @deprecated Use vana.data.upload() instead for the high-level API with automatic encryption and schema validation
36953
+ * @deprecated Since v2.0.0 - Use vana.data.upload() instead for the high-level API with automatic encryption and schema validation
36954
+ *
36955
+ * Migration guide:
36956
+ * ```typescript
36957
+ * // Old way (deprecated):
36958
+ * const encrypted = await encryptBlob(data, key);
36959
+ * const result = await vana.data.uploadEncryptedFileWithSchema(encrypted, schemaId, filename);
36960
+ *
36961
+ * // New way:
36962
+ * const result = await vana.data.upload({
36963
+ * content: data,
36964
+ * filename: filename,
36965
+ * schemaId: schemaId, // Automatic validation
36966
+ * encrypt: true
36967
+ * });
36968
+ * ```
36465
36969
  * @param encryptedFile - The encrypted file blob to upload
36466
36970
  * @param schemaId - The schema ID to associate with the file
36467
36971
  * @param filename - Optional filename for the upload
@@ -36604,6 +37108,7 @@ var DataController = class {
36604
37108
  * Gets the user's address from the wallet client.
36605
37109
  *
36606
37110
  * @returns Promise resolving to the user's wallet address
37111
+ * @throws {Error} When no addresses are available in wallet client
36607
37112
  */
36608
37113
  async getUserAddress() {
36609
37114
  const addresses = await this.context.walletClient.getAddresses();
@@ -36619,6 +37124,10 @@ var DataController = class {
36619
37124
  * @param ownerAddress - The address of the file owner
36620
37125
  * @param permissions - Array of permissions to set for the file
36621
37126
  * @returns Promise resolving to file ID and transaction hash
37127
+ * @throws {Error} When chain ID is not available
37128
+ * @throws {ContractError} When contract execution fails
37129
+ * @throws {Error} When transaction receipt is not available
37130
+ * @throws {Error} When FileAdded event cannot be parsed
36622
37131
  *
36623
37132
  * This method handles the core logic of registering a file
36624
37133
  * with specific permissions on the DataRegistry contract. It can be used
@@ -36683,6 +37192,10 @@ var DataController = class {
36683
37192
  * @param permissions - Array of permissions to grant (account and encrypted key)
36684
37193
  * @param schemaId - The schema ID to associate with the file (0 for no schema)
36685
37194
  * @returns Promise resolving to object with fileId and transactionHash
37195
+ * @throws {Error} When chain ID is not available
37196
+ * @throws {ContractError} When contract execution fails
37197
+ * @throws {Error} When transaction receipt is not available
37198
+ * @throws {Error} When FileAdded event cannot be parsed
36686
37199
  */
36687
37200
  async addFileWithPermissionsAndSchema(url, ownerAddress, permissions = [], schemaId = 0) {
36688
37201
  try {
@@ -36737,7 +37250,24 @@ var DataController = class {
36737
37250
  /**
36738
37251
  * Adds a new schema to the DataRefinerRegistry.
36739
37252
  *
36740
- * @deprecated Use vana.schemas.create() instead for the high-level API with automatic IPFS upload
37253
+ * @deprecated Since v2.0.0 - Use vana.schemas.create() instead for the high-level API with automatic IPFS upload
37254
+ *
37255
+ * Migration guide:
37256
+ * ```typescript
37257
+ * // Old way (deprecated):
37258
+ * const result = await vana.data.addSchema({
37259
+ * name: "UserProfile",
37260
+ * type: "JSON",
37261
+ * definitionUrl: "ipfs://..."
37262
+ * });
37263
+ *
37264
+ * // New way:
37265
+ * const result = await vana.schemas.create({
37266
+ * name: "UserProfile",
37267
+ * type: "JSON",
37268
+ * definition: schemaObject // Automatically uploads to IPFS
37269
+ * });
37270
+ * ```
36741
37271
  * @param params - Schema parameters including name, type, and definition URL
36742
37272
  * @returns Promise resolving to the new schema ID and transaction hash
36743
37273
  */
@@ -36796,7 +37326,16 @@ var DataController = class {
36796
37326
  /**
36797
37327
  * Retrieves a schema by its ID.
36798
37328
  *
36799
- * @deprecated Use vana.schemas.get() instead
37329
+ * @deprecated Since v2.0.0 - Use vana.schemas.get() instead
37330
+ *
37331
+ * Migration guide:
37332
+ * ```typescript
37333
+ * // Old way (deprecated):
37334
+ * const schema = await vana.data.getSchema(schemaId);
37335
+ *
37336
+ * // New way:
37337
+ * const schema = await vana.schemas.get(schemaId);
37338
+ * ```
36800
37339
  * @param schemaId - The schema ID to retrieve
36801
37340
  * @returns Promise resolving to the schema information
36802
37341
  */
@@ -36842,7 +37381,16 @@ var DataController = class {
36842
37381
  /**
36843
37382
  * Gets the total number of schemas in the registry.
36844
37383
  *
36845
- * @deprecated Use vana.schemas.count() instead
37384
+ * @deprecated Since v2.0.0 - Use vana.schemas.count() instead
37385
+ *
37386
+ * Migration guide:
37387
+ * ```typescript
37388
+ * // Old way (deprecated):
37389
+ * const count = await vana.data.getSchemasCount();
37390
+ *
37391
+ * // New way:
37392
+ * const count = await vana.schemas.count();
37393
+ * ```
36846
37394
  * @returns Promise resolving to the total schema count
36847
37395
  */
36848
37396
  async getSchemasCount() {
@@ -37091,6 +37639,7 @@ var DataController = class {
37091
37639
  try {
37092
37640
  const userEncryptionKey = await generateEncryptionKey(
37093
37641
  this.context.walletClient,
37642
+ this.context.platform,
37094
37643
  DEFAULT_ENCRYPTION_SEED
37095
37644
  );
37096
37645
  const encryptedData = await encryptBlobWithSignedKey(
@@ -37156,16 +37705,50 @@ var DataController = class {
37156
37705
  * 1. Gets the user's encryption key
37157
37706
  * 2. Encrypts the user's encryption key with the provided public key
37158
37707
  * 3. Adds the permission to the file
37708
+ * 4. Returns the permission data from the blockchain event
37709
+ *
37710
+ * For advanced users who need more control over transaction timing,
37711
+ * use `submitFilePermission()` instead.
37712
+ *
37713
+ * @param fileId - The ID of the file to add permissions for
37714
+ * @param account - The address of the account to grant permission to
37715
+ * @param publicKey - The public key to encrypt the user's encryption key with (hex string with 0x prefix)
37716
+ * @returns Promise resolving to permission data from PermissionGranted event
37717
+ * @throws {Error} "No addresses available in wallet client" - When wallet is not connected
37718
+ * @throws {Error} "Chain ID not available" - When wallet chain is not configured
37719
+ * @throws {Error} "Failed to add permission to file: {error}" - When transaction fails or user doesn't own file
37720
+ * @example
37721
+ * ```typescript
37722
+ * const result = await vana.data.addPermissionToFile(fileId, account, publicKey);
37723
+ * console.log(`Permission granted to ${result.account} for file ${result.fileId}`);
37724
+ * console.log(`Transaction: ${result.transactionHash}`);
37725
+ * ```
37726
+ */
37727
+ async addPermissionToFile(fileId, account, publicKey) {
37728
+ const txHash = await this.submitFilePermission(fileId, account, publicKey);
37729
+ return parseTransactionResult(this.context, txHash, "addFilePermission");
37730
+ }
37731
+ /**
37732
+ * Submits a file permission transaction and returns the transaction hash immediately.
37733
+ *
37734
+ * This is the lower-level method that provides maximum control over transaction timing.
37735
+ * Use this when you want to handle transaction confirmation and event parsing separately.
37159
37736
  *
37160
37737
  * @param fileId - The ID of the file to add permissions for
37161
37738
  * @param account - The address of the account to grant permission to
37162
37739
  * @param publicKey - The public key to encrypt the user's encryption key with
37163
37740
  * @returns Promise resolving to the transaction hash
37741
+ * @example
37742
+ * ```typescript
37743
+ * const txHash = await vana.data.submitFilePermission(fileId, account, publicKey);
37744
+ * console.log(`Transaction submitted: ${txHash}`);
37745
+ * ```
37164
37746
  */
37165
- async addPermissionToFile(fileId, account, publicKey) {
37747
+ async submitFilePermission(fileId, account, publicKey) {
37166
37748
  try {
37167
37749
  const userEncryptionKey = await generateEncryptionKey(
37168
37750
  this.context.walletClient,
37751
+ this.context.platform,
37169
37752
  DEFAULT_ENCRYPTION_SEED
37170
37753
  );
37171
37754
  const encryptedKey = await encryptWithWalletPublicKey(
@@ -37286,7 +37869,9 @@ var DataController = class {
37286
37869
  *
37287
37870
  * @param url - The URL to fetch content from
37288
37871
  * @returns Promise resolving to the fetched content as a Blob
37289
- * @throws {Error} When the fetch fails or returns a non-ok response
37872
+ * @throws {Error} "HTTP error! status: {status} {statusText}" - When server returns error status
37873
+ * @throws {Error} "Empty response" - When server returns no content
37874
+ * @throws {Error} "Network error: Failed to fetch from {url}" - When network request fails
37290
37875
  *
37291
37876
  * @example
37292
37877
  * ```typescript
@@ -37338,7 +37923,10 @@ var DataController = class {
37338
37923
  * @param options - Optional configuration
37339
37924
  * @param options.gateways - Array of IPFS gateway URLs to try (must end with /)
37340
37925
  * @returns Promise resolving to the fetched content as a Blob
37341
- * @throws {Error} When all gateways fail to fetch the content
37926
+ * @throws {Error} "Invalid IPFS URL format" - When URL is not ipfs:// or valid CID
37927
+ * @throws {Error} "Empty response" - When gateway returns no content
37928
+ * @throws {Error} "HTTP error! status: {status}" - When gateway returns error status
37929
+ * @throws {Error} "Failed to fetch IPFS content {cid} from all gateways" - When all gateways fail
37342
37930
  *
37343
37931
  * @example
37344
37932
  * ```typescript
@@ -37879,6 +38467,39 @@ var ServerController = class {
37879
38467
  this.context = context;
37880
38468
  }
37881
38469
  PERSONAL_SERVER_BASE_URL = process.env.NEXT_PUBLIC_PERSONAL_SERVER_BASE_URL;
38470
+ /**
38471
+ * Retrieves the cryptographic identity of a personal server.
38472
+ *
38473
+ * @remarks
38474
+ * This method fetches the public key and metadata for a personal server,
38475
+ * which is required for encrypting data before sharing with the server.
38476
+ * The identity includes the server's public key, address, and operational
38477
+ * details needed for secure communication. This information is cached
38478
+ * by identity servers to enable offline key retrieval.
38479
+ *
38480
+ * @param request - Parameters containing the user address
38481
+ * @param request.userAddress - The wallet address associated with the personal server
38482
+ * @returns Promise resolving to the server's identity information
38483
+ * @throws {NetworkError} When the identity service is unavailable or returns invalid data
38484
+ * @throws {PersonalServerError} When server identity cannot be retrieved
38485
+ * @example
38486
+ * ```typescript
38487
+ * // Get server identity for data encryption
38488
+ * const identity = await vana.server.getIdentity({
38489
+ * userAddress: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36"
38490
+ * });
38491
+ *
38492
+ * console.log(`Server: ${identity.name}`);
38493
+ * console.log(`Address: ${identity.address}`);
38494
+ * console.log(`Public Key: ${identity.public_key}`);
38495
+ *
38496
+ * // Use the public key for encrypting data to share with this server
38497
+ * const encryptedData = await encryptWithWalletPublicKey(
38498
+ * userData,
38499
+ * identity.public_key
38500
+ * );
38501
+ * ```
38502
+ */
37882
38503
  async getIdentity(request) {
37883
38504
  try {
37884
38505
  const response = await fetch(
@@ -37921,10 +38542,13 @@ var ServerController = class {
37921
38542
  * This method submits a computation request to the personal server API.
37922
38543
  * The response includes the operation ID.
37923
38544
  * @param params - The request parameters object
37924
- * @param params.permissionId - The permission ID authorizing this operation
38545
+ * @param params.permissionId - The permission ID authorizing this operation.
38546
+ * Obtain from granted permissions via `vana.permissions.getUserPermissionGrantsOnChain()`.
37925
38547
  * @returns A Promise that resolves to an operation response with status and control URLs
37926
- * @throws {PersonalServerError} When server request fails or parameters are invalid
37927
- * @throws {NetworkError} When personal server API communication fails
38548
+ * @throws {PersonalServerError} When server request fails or parameters are invalid.
38549
+ * Verify permissionId exists and is active for the target server.
38550
+ * @throws {NetworkError} When personal server API communication fails.
38551
+ * Check server URL configuration and network connectivity.
37928
38552
  * @example
37929
38553
  * ```typescript
37930
38554
  * const response = await vana.server.createOperation({
@@ -38026,6 +38650,50 @@ var ServerController = class {
38026
38650
  );
38027
38651
  }
38028
38652
  }
38653
+ /**
38654
+ * Cancels a running operation on the personal server.
38655
+ *
38656
+ * @remarks
38657
+ * This method attempts to cancel an operation that is currently processing
38658
+ * on the personal server. The operation must be in a cancellable state
38659
+ * (typically `starting` or `processing`). Not all operations support
38660
+ * cancellation, and cancellation may not be immediate. The server will
38661
+ * attempt to stop the operation and update its status to `canceled`.
38662
+ *
38663
+ * **Cancellation Behavior:**
38664
+ * - Operations in `succeeded` or `failed` states cannot be canceled
38665
+ * - Some long-running operations may take time to respond to cancellation
38666
+ * - Always verify cancellation by polling the operation status afterward
38667
+ *
38668
+ * @param operationId - The unique identifier of the operation to cancel,
38669
+ * obtained from `createOperation()` response
38670
+ * @returns Promise that resolves when the cancellation request is accepted
38671
+ * @throws {PersonalServerError} When the operation cannot be canceled or doesn't exist.
38672
+ * Check operation status - it may already be completed or failed.
38673
+ * @throws {NetworkError} When unable to reach the personal server API.
38674
+ * Verify server URL and network connectivity.
38675
+ * @example
38676
+ * ```typescript
38677
+ * // Start a long-running operation
38678
+ * const operation = await vana.server.createOperation({
38679
+ * permissionId: 123
38680
+ * });
38681
+ *
38682
+ * // Cancel if needed
38683
+ * try {
38684
+ * await vana.server.cancelOperation(operation.id);
38685
+ * console.log("Cancellation requested");
38686
+ *
38687
+ * // Verify cancellation
38688
+ * const status = await vana.server.getOperation(operation.id);
38689
+ * if (status.status === "canceled") {
38690
+ * console.log("Operation successfully canceled");
38691
+ * }
38692
+ * } catch (error) {
38693
+ * console.error("Failed to cancel:", error);
38694
+ * }
38695
+ * ```
38696
+ */
38029
38697
  async cancelOperation(operationId) {
38030
38698
  try {
38031
38699
  const response = await fetch(
@@ -38329,7 +38997,8 @@ var ProtocolController = class {
38329
38997
  * are actually deployed on the current network.
38330
38998
  * @param contractName - The name of the Vana contract to retrieve (use const assertion for full typing)
38331
38999
  * @returns An object containing the contract's address and fully typed ABI
38332
- * @throws {ContractNotFoundError} When the contract is not deployed on the current chain
39000
+ * @throws {ContractNotFoundError} When the contract is not deployed on the current chain.
39001
+ * Verify contract name spelling and check current network with `getChainId()`.
38333
39002
  * @example
38334
39003
  * ```typescript
38335
39004
  * // Get contract info with full type inference
@@ -38438,6 +39107,7 @@ var ProtocolController = class {
38438
39107
  * Gets the current chain ID from the wallet client.
38439
39108
  *
38440
39109
  * @returns The chain ID
39110
+ * @throws {Error} When chain ID is not available from wallet client
38441
39111
  */
38442
39112
  getChainId() {
38443
39113
  const chainId = this.context.walletClient.chain?.id;
@@ -38450,6 +39120,7 @@ var ProtocolController = class {
38450
39120
  * Gets the current chain name from the wallet client.
38451
39121
  *
38452
39122
  * @returns The chain name
39123
+ * @throws {Error} When chain name is not available from wallet client
38453
39124
  */
38454
39125
  getChainName() {
38455
39126
  const chainName = this.context.walletClient.chain?.name;
@@ -38950,6 +39621,7 @@ var GoogleDriveStorage = class {
38950
39621
  };
38951
39622
 
38952
39623
  // src/storage/providers/ipfs.ts
39624
+ init_crypto_utils();
38953
39625
  var IpfsStorage = class _IpfsStorage {
38954
39626
  constructor(config) {
38955
39627
  this.config = config;
@@ -38989,7 +39661,7 @@ var IpfsStorage = class _IpfsStorage {
38989
39661
  * ```
38990
39662
  */
38991
39663
  static forInfura(credentials) {
38992
- const auth = btoa(`${credentials.projectId}:${credentials.projectSecret}`);
39664
+ const auth = toBase64(`${credentials.projectId}:${credentials.projectSecret}`);
38993
39665
  return new _IpfsStorage({
38994
39666
  apiEndpoint: "https://ipfs.infura.io:5001/api/v0/add",
38995
39667
  gatewayUrl: "https://ipfs.infura.io/ipfs",
@@ -40279,15 +40951,35 @@ var VanaCore = class {
40279
40951
  }
40280
40952
  /**
40281
40953
  * Encrypts data using the Vana protocol standard encryption.
40282
- * This method automatically uses the correct platform adapter for the current environment.
40954
+ *
40955
+ * @remarks
40956
+ * This method implements the Vana network's standard encryption protocol using
40957
+ * platform-appropriate cryptographic libraries. It automatically handles different
40958
+ * input types (string or Blob) and produces encrypted output suitable for secure
40959
+ * storage or transmission. The encryption is compatible with the network's
40960
+ * decryption protocols and can be decrypted by authorized parties.
40283
40961
  *
40284
- * @param data The data to encrypt (string or Blob)
40285
- * @param key The key to use as encryption key
40286
- * @returns The encrypted data as Blob
40962
+ * @param data - The data to encrypt (string or Blob)
40963
+ * @param key - The encryption key (typically generated via `generateEncryptionKey`)
40964
+ * @returns The encrypted data as a Blob
40965
+ * @throws {Error} When encryption fails due to invalid key or data format
40287
40966
  * @example
40288
40967
  * ```typescript
40289
- * const encryptionKey = await generateEncryptionKey(walletClient);
40290
- * const encrypted = await vana.encryptBlob("sensitive data", encryptionKey);
40968
+ * import { generateEncryptionKey } from '@opendatalabs/vana-sdk/node';
40969
+ *
40970
+ * // Generate encryption key from wallet signature
40971
+ * const encryptionKey = await generateEncryptionKey(vana.walletClient);
40972
+ *
40973
+ * // Encrypt string data
40974
+ * const sensitiveData = "User's private information";
40975
+ * const encrypted = await vana.encryptBlob(sensitiveData, encryptionKey);
40976
+ *
40977
+ * // Encrypt file data
40978
+ * const fileBlob = new Blob([fileContent], { type: 'application/json' });
40979
+ * const encryptedFile = await vana.encryptBlob(fileBlob, encryptionKey);
40980
+ *
40981
+ * // Store encrypted data safely
40982
+ * await storageProvider.upload(encrypted, 'encrypted-data.bin');
40291
40983
  * ```
40292
40984
  */
40293
40985
  async encryptBlob(data, key) {
@@ -40295,16 +40987,52 @@ var VanaCore = class {
40295
40987
  }
40296
40988
  /**
40297
40989
  * Decrypts data that was encrypted using the Vana protocol.
40298
- * This method automatically uses the correct platform adapter for the current environment.
40990
+ *
40991
+ * @remarks
40992
+ * This method decrypts data that was previously encrypted using the Vana network's
40993
+ * standard encryption protocol. It requires the same wallet signature that was used
40994
+ * for encryption and automatically uses the appropriate platform adapter for
40995
+ * cryptographic operations. The decrypted output maintains the original data format.
40299
40996
  *
40300
- * @param encryptedData The encrypted data (string or Blob)
40301
- * @param walletSignature The wallet signature to use as decryption key
40302
- * @returns The decrypted data as Blob
40997
+ * @param encryptedData - The encrypted data (string or Blob)
40998
+ * @param walletSignature - The wallet signature used as decryption key
40999
+ * @returns The decrypted data as a Blob
41000
+ * @throws {Error} When decryption fails due to invalid signature or corrupted data
40303
41001
  * @example
40304
41002
  * ```typescript
40305
- * const encryptionKey = await generateEncryptionKey(walletClient);
40306
- * const decrypted = await vana.decryptBlob(encryptedData, encryptionKey);
40307
- * const text = await decrypted.text();
41003
+ * import { generateEncryptionKey } from '@opendatalabs/vana-sdk/node';
41004
+ *
41005
+ * // Retrieve encrypted data from storage
41006
+ * const encryptedBlob = await storageProvider.download('encrypted-data.bin');
41007
+ *
41008
+ * // Generate the same key used for encryption
41009
+ * const decryptionKey = await generateEncryptionKey(vana.walletClient);
41010
+ *
41011
+ * // Decrypt the data
41012
+ * const decrypted = await vana.decryptBlob(encryptedBlob, decryptionKey);
41013
+ *
41014
+ * // Convert back to original format
41015
+ * const originalText = await decrypted.text();
41016
+ * const originalJson = JSON.parse(originalText);
41017
+ *
41018
+ * console.log('Decrypted data:', originalJson);
41019
+ * ```
41020
+ *
41021
+ * @example
41022
+ * ```typescript
41023
+ * // Decrypt file downloaded from Vana network
41024
+ * const userFiles = await vana.data.getUserFiles();
41025
+ * const file = userFiles[0];
41026
+ *
41027
+ * // Download encrypted content
41028
+ * const encrypted = await fetch(file.url).then(r => r.blob());
41029
+ *
41030
+ * // Decrypt with user's key
41031
+ * const decryptionKey = await generateEncryptionKey(vana.walletClient);
41032
+ * const decrypted = await vana.decryptBlob(encrypted, decryptionKey);
41033
+ *
41034
+ * // Process original data
41035
+ * const fileContent = await decrypted.arrayBuffer();
40308
41036
  * ```
40309
41037
  */
40310
41038
  async decryptBlob(encryptedData, walletSignature) {
@@ -41257,6 +41985,7 @@ export {
41257
41985
  SerializationError,
41258
41986
  ServerController,
41259
41987
  ServerUrlMismatchError,
41988
+ SignatureCache,
41260
41989
  SignatureError,
41261
41990
  StorageError,
41262
41991
  StorageManager,
@@ -41331,6 +42060,7 @@ export {
41331
42060
  validateGrantFile,
41332
42061
  validateGranteeAccess,
41333
42062
  validateOperationAccess,
41334
- vanaMainnet2 as vanaMainnet
42063
+ vanaMainnet2 as vanaMainnet,
42064
+ withSignatureCache
41335
42065
  };
41336
42066
  //# sourceMappingURL=index.node.js.map