@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.
@@ -29,6 +29,28 @@ function parseEncryptedDataBuffer(encryptedBuffer) {
29
29
  mac: encryptedBuffer.slice(-32)
30
30
  };
31
31
  }
32
+ function toBase64(str) {
33
+ if (typeof Buffer !== "undefined") {
34
+ return Buffer.from(str, "utf8").toString("base64");
35
+ } else if (typeof btoa !== "undefined") {
36
+ return btoa(str);
37
+ } else {
38
+ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
39
+ let result = "";
40
+ let i = 0;
41
+ while (i < str.length) {
42
+ const a = str.charCodeAt(i++);
43
+ const b = i < str.length ? str.charCodeAt(i++) : 0;
44
+ const c = i < str.length ? str.charCodeAt(i++) : 0;
45
+ const bitmap = a << 16 | b << 8 | c;
46
+ result += chars.charAt(bitmap >> 18 & 63);
47
+ result += chars.charAt(bitmap >> 12 & 63);
48
+ result += i - 2 < str.length ? chars.charAt(bitmap >> 6 & 63) : "=";
49
+ result += i - 1 < str.length ? chars.charAt(bitmap & 63) : "=";
50
+ }
51
+ return result;
52
+ }
53
+ }
32
54
  var init_crypto_utils = __esm({
33
55
  "src/platform/shared/crypto-utils.ts"() {
34
56
  "use strict";
@@ -79,7 +101,7 @@ var init_error_utils = __esm({
79
101
 
80
102
  // src/platform/browser.ts
81
103
  import * as openpgp from "openpgp";
82
- var BrowserCryptoAdapter, BrowserPGPAdapter, BrowserHttpAdapter, BrowserPlatformAdapter, browserPlatformAdapter;
104
+ var BrowserCryptoAdapter, BrowserPGPAdapter, BrowserHttpAdapter, BrowserCacheAdapter, BrowserPlatformAdapter, browserPlatformAdapter;
83
105
  var init_browser = __esm({
84
106
  "src/platform/browser.ts"() {
85
107
  "use strict";
@@ -258,15 +280,62 @@ var init_browser = __esm({
258
280
  return fetch(url, options);
259
281
  }
260
282
  };
283
+ BrowserCacheAdapter = class {
284
+ constructor() {
285
+ __publicField(this, "prefix", "vana_cache_");
286
+ }
287
+ get(key) {
288
+ try {
289
+ if (typeof sessionStorage === "undefined") {
290
+ return null;
291
+ }
292
+ return sessionStorage.getItem(this.prefix + key);
293
+ } catch {
294
+ return null;
295
+ }
296
+ }
297
+ set(key, value) {
298
+ try {
299
+ if (typeof sessionStorage !== "undefined") {
300
+ sessionStorage.setItem(this.prefix + key, value);
301
+ }
302
+ } catch {
303
+ }
304
+ }
305
+ delete(key) {
306
+ try {
307
+ if (typeof sessionStorage !== "undefined") {
308
+ sessionStorage.removeItem(this.prefix + key);
309
+ }
310
+ } catch {
311
+ }
312
+ }
313
+ clear() {
314
+ try {
315
+ if (typeof sessionStorage === "undefined") {
316
+ return;
317
+ }
318
+ const keys = Object.keys(sessionStorage);
319
+ for (const key of keys) {
320
+ if (key.startsWith(this.prefix)) {
321
+ sessionStorage.removeItem(key);
322
+ }
323
+ }
324
+ } catch {
325
+ }
326
+ }
327
+ };
261
328
  BrowserPlatformAdapter = class {
262
329
  constructor() {
263
330
  __publicField(this, "crypto");
264
331
  __publicField(this, "pgp");
265
332
  __publicField(this, "http");
333
+ __publicField(this, "cache");
266
334
  __publicField(this, "platform", "browser");
267
335
  this.crypto = new BrowserCryptoAdapter();
268
336
  this.pgp = new BrowserPGPAdapter();
269
337
  this.http = new BrowserHttpAdapter();
338
+ this.cache = new BrowserCacheAdapter();
270
339
  }
271
340
  };
272
341
  browserPlatformAdapter = new BrowserPlatformAdapter();
@@ -800,276 +869,45 @@ var PermissionError = class extends VanaError {
800
869
  }
801
870
  };
802
871
 
803
- // src/config/addresses.ts
804
- var CONTRACTS = {
805
- // Core Platform Contracts
806
- DataPermissions: {
807
- addresses: {
808
- 14800: "0x31fb1D48f6B2265A4cAD516BC39E96a18fb7c8de",
809
- 1480: "0x31fb1D48f6B2265A4cAD516BC39E96a18fb7c8de"
810
- }
811
- },
812
- DataRegistry: {
813
- addresses: {
814
- 14800: "0x8C8788f98385F6ba1adD4234e551ABba0f82Cb7C",
815
- 1480: "0x8C8788f98385F6ba1adD4234e551ABba0f82Cb7C"
816
- }
817
- },
818
- TeePoolPhala: {
819
- addresses: {
820
- 14800: "0xE8EC6BD73b23Ad40E6B9a6f4bD343FAc411bD99A",
821
- 1480: "0xE8EC6BD73b23Ad40E6B9a6f4bD343FAc411bD99A"
822
- }
823
- },
824
- ComputeEngine: {
825
- addresses: {
826
- 14800: "0xb2BFe33FA420c45F1Cf1287542ad81ae935447bd",
827
- 1480: "0xb2BFe33FA420c45F1Cf1287542ad81ae935447bd"
828
- }
829
- },
830
- // Data Access Infrastructure
831
- DataRefinerRegistry: {
832
- addresses: {
833
- 14800: "0x93c3EF89369fDcf08Be159D9DeF0F18AB6Be008c",
834
- 1480: "0x93c3EF89369fDcf08Be159D9DeF0F18AB6Be008c"
835
- }
836
- },
837
- QueryEngine: {
838
- addresses: {
839
- 14800: "0xd25Eb66EA2452cf3238A2eC6C1FD1B7F5B320490",
840
- 1480: "0xd25Eb66EA2452cf3238A2eC6C1FD1B7F5B320490"
841
- }
842
- },
843
- VanaTreasury: {
844
- addresses: {
845
- 14800: "0x94a1E56e555ac48d092f490fB10CDFaB434915eD",
846
- 1480: "0x94a1E56e555ac48d092f490fB10CDFaB434915eD"
847
- }
848
- },
849
- ComputeInstructionRegistry: {
850
- addresses: {
851
- 14800: "0x5786B12b4c6Ba2bFAF0e77Ed30Bf6d32805563A5",
852
- 1480: "0x5786B12b4c6Ba2bFAF0e77Ed30Bf6d32805563A5"
853
- }
854
- },
855
- // TEE Pool Variants
856
- TeePoolEphemeralStandard: {
857
- addresses: {
858
- 14800: "0xe124bae846D5ec157f75Bd9e68ca87C4d2AB835A",
859
- 1480: "0xe124bae846D5ec157f75Bd9e68ca87C4d2AB835A"
860
- }
861
- },
862
- TeePoolPersistentStandard: {
863
- addresses: {
864
- 14800: "0xe8bB8d0629651Cf33e0845d743976Dc1f0971d76",
865
- 1480: "0xe8bB8d0629651Cf33e0845d743976Dc1f0971d76"
866
- }
867
- },
868
- TeePoolPersistentGpu: {
869
- addresses: {
870
- 14800: "0x1c346Cd74f8551f8fa13f3F4b6b8dAE22338E6a9",
871
- 1480: "0x1c346Cd74f8551f8fa13f3F4b6b8dAE22338E6a9"
872
- }
873
- },
874
- TeePoolDedicatedStandard: {
875
- addresses: {
876
- 14800: "0xf024b7ac5E8417416f53B41ecfa58C8e9396687d",
877
- 1480: "0xf024b7ac5E8417416f53B41ecfa58C8e9396687d"
878
- }
879
- },
880
- TeePoolDedicatedGpu: {
881
- addresses: {
882
- 14800: "0xB1686FA9620bBf851714d1cB47b8a4Bf4664644E",
883
- 1480: "0xB1686FA9620bBf851714d1cB47b8a4Bf4664644E"
884
- }
885
- },
886
- // DLP Reward System
887
- VanaEpoch: {
888
- addresses: {
889
- 14800: "0x2063cFF0609D59bCCc196E20Eb58A8696a6b15A0",
890
- 1480: "0x2063cFF0609D59bCCc196E20Eb58A8696a6b15A0"
891
- }
892
- },
893
- DLPRegistry: {
894
- addresses: {
895
- 14800: "0x4D59880a924526d1dD33260552Ff4328b1E18a43",
896
- 1480: "0x4D59880a924526d1dD33260552Ff4328b1E18a43"
897
- }
898
- },
899
- DLPRegistryTreasury: {
900
- addresses: {
901
- 14800: "0xb12ce1d27bEeFe39b6F0110b1AB77C21Aa0c9F9a",
902
- 1480: "0xb12ce1d27bEeFe39b6F0110b1AB77C21Aa0c9F9a"
903
- }
904
- },
905
- DLPPerformance: {
906
- addresses: {
907
- 14800: "0x847715C7DB37cF286611182Be0bD333cbfa29cc1",
908
- 1480: "0x847715C7DB37cF286611182Be0bD333cbfa29cc1"
909
- }
910
- },
911
- DLPRewardDeployer: {
912
- addresses: {
913
- 14800: "0xEFD0F9Ba9De70586b7c4189971cF754adC923B04",
914
- 1480: "0xEFD0F9Ba9De70586b7c4189971cF754adC923B04"
915
- }
916
- },
917
- DLPRewardDeployerTreasury: {
918
- addresses: {
919
- 14800: "0xb547ca8Fe4990fe330FeAeb1C2EBb42F925Af5b8",
920
- 1480: "0xb547ca8Fe4990fe330FeAeb1C2EBb42F925Af5b8"
921
- }
922
- },
923
- DLPRewardSwap: {
924
- addresses: {
925
- 14800: "0x7c6862C46830F0fc3bF3FF509EA1bD0EE7267fB0",
926
- 1480: "0x7c6862C46830F0fc3bF3FF509EA1bD0EE7267fB0"
927
- }
928
- },
929
- SwapHelper: {
930
- addresses: {
931
- 14800: "0x55D5e6F73326315bF2E091e97F04f0770e5C54e2",
932
- 1480: "0x55D5e6F73326315bF2E091e97F04f0770e5C54e2"
933
- }
934
- },
935
- // VanaPool (Staking)
936
- VanaPoolStaking: {
937
- addresses: {
938
- 14800: "0x641C18E2F286c86f96CE95C8ec1EB9fC0415Ca0e",
939
- 1480: "0x641C18E2F286c86f96CE95C8ec1EB9fC0415Ca0e"
940
- }
941
- },
942
- VanaPoolEntity: {
943
- addresses: {
944
- 14800: "0x44f20490A82e1f1F1cC25Dd3BA8647034eDdce30",
945
- 1480: "0x44f20490A82e1f1F1cC25Dd3BA8647034eDdce30"
946
- }
947
- },
948
- VanaPoolTreasury: {
949
- addresses: {
950
- 14800: "0x143BE72CF2541604A7691933CAccd6D9cC17c003",
951
- 1480: "0x143BE72CF2541604A7691933CAccd6D9cC17c003"
952
- }
953
- },
954
- // DLP Deployment Contracts
955
- DAT: {
956
- addresses: {
957
- 14800: "0xA706b93ccED89f13340673889e29F0a5cd84212d",
958
- 1480: "0xA706b93ccED89f13340673889e29F0a5cd84212d"
959
- }
960
- },
961
- DATFactory: {
962
- addresses: {
963
- 14800: "0x40f8bccF35a75ecef63BC3B1B3E06ffEB9220644",
964
- 1480: "0x40f8bccF35a75ecef63BC3B1B3E06ffEB9220644"
965
- }
966
- },
967
- DATPausable: {
968
- addresses: {
969
- 14800: "0xe69FE86f0B95cC2f8416Fe22815c85DC8887e76e",
970
- 1480: "0xe69FE86f0B95cC2f8416Fe22815c85DC8887e76e"
971
- }
972
- },
973
- DATVotes: {
974
- addresses: {
975
- 14800: "0xaE04c8A77E9B27869eb563720524A9aE0baf1831",
976
- 1480: "0xaE04c8A77E9B27869eb563720524A9aE0baf1831"
977
- }
978
- },
979
- // Utility Contracts (no ABIs in SDK)
980
- Multicall3: {
981
- addresses: {
982
- 14800: "0xD8d2dFca27E8797fd779F8547166A2d3B29d360E",
983
- 1480: "0xD8d2dFca27E8797fd779F8547166A2d3B29d360E"
984
- }
985
- },
986
- Multisend: {
987
- addresses: {
988
- 14800: "0x8807e8BCDFbaA8c2761760f3FBA37F6f7F2C5b2d",
989
- 1480: "0x8807e8BCDFbaA8c2761760f3FBA37F6f7F2C5b2d"
990
- }
991
- }
992
- };
993
- var LEGACY_CONTRACTS = {
994
- // DEPRECATED: Original Intel SGX TeePool (PRO-347)
995
- TeePool: {
996
- addresses: {
997
- 14800: "0x3c92fD91639b41f13338CE62f19131e7d19eaa0D",
998
- 1480: "0x3c92fD91639b41f13338CE62f19131e7d19eaa0D"
999
- }
1000
- },
1001
- // DEPRECATED: DLPRoot system (replaced by VanaPool + DLPRewards)
1002
- DLPRootEpoch: {
1003
- addresses: {
1004
- 14800: "0xc3d176cF6BccFCB9225b53B87a95147218e1537F",
1005
- 1480: "0xc3d176cF6BccFCB9225b53B87a95147218e1537F"
1006
- }
1007
- },
1008
- DLPRootCore: {
1009
- addresses: {
1010
- 14800: "0x0aBa5e28228c323A67712101d61a54d4ff5720FD",
1011
- 1480: "0x0aBa5e28228c323A67712101d61a54d4ff5720FD"
1012
- }
1013
- },
1014
- DLPRoot: {
1015
- addresses: {
1016
- 14800: "0xff14346dF2B8Fd0c95BF34f1c92e49417b508AD5",
1017
- 1480: "0xff14346dF2B8Fd0c95BF34f1c92e49417b508AD5"
1018
- }
1019
- },
1020
- DLPRootMetrics: {
1021
- addresses: {
1022
- 14800: "0xbb532917B6407c060Afd9Cb7d53527eCb91d6662",
1023
- 1480: "0xbb532917B6407c060Afd9Cb7d53527eCb91d6662"
1024
- }
1025
- },
1026
- DLPRootStakesTreasury: {
1027
- addresses: {
1028
- 14800: "0x52c3260ED5C235fcA43524CF508e29c897318775",
1029
- 1480: "0x52c3260ED5C235fcA43524CF508e29c897318775"
1030
- }
1031
- },
1032
- DLPRootRewardsTreasury: {
1033
- addresses: {
1034
- 14800: "0xDBFb6B8b9E2eCAEbdE64d665cD553dB81e524479",
1035
- 1480: "0xDBFb6B8b9E2eCAEbdE64d665cD553dB81e524479"
1036
- }
1037
- }
1038
- };
1039
- var CONTRACT_ADDRESSES = {
1040
- 14800: Object.fromEntries(
1041
- Object.entries(CONTRACTS).map(([name, info]) => [name, info.addresses[14800]]).filter(([, addr]) => addr)
1042
- ),
1043
- 1480: Object.fromEntries(
1044
- Object.entries(CONTRACTS).map(([name, info]) => [name, info.addresses[1480]]).filter(([, addr]) => addr)
1045
- )
1046
- };
1047
- var UTILITY_ADDRESSES = {
1048
- 14800: {
1049
- Multicall3: CONTRACTS.Multicall3.addresses[14800],
1050
- Multisend: CONTRACTS.Multisend.addresses[14800]
1051
- },
1052
- 1480: {
1053
- Multicall3: CONTRACTS.Multicall3.addresses[1480],
1054
- Multisend: CONTRACTS.Multisend.addresses[1480]
1055
- }
1056
- };
1057
- var LEGACY_ADDRESSES = {
1058
- 14800: Object.fromEntries(
1059
- Object.entries(LEGACY_CONTRACTS).map(([name, info]) => [name, info.addresses[14800]]).filter(([, addr]) => addr)
1060
- ),
1061
- 1480: Object.fromEntries(
1062
- Object.entries(LEGACY_CONTRACTS).map(([name, info]) => [name, info.addresses[1480]]).filter(([, addr]) => addr)
1063
- )
1064
- };
1065
- var getContractAddress = (chainId, contract) => {
1066
- const contractAddress = CONTRACT_ADDRESSES[chainId]?.[contract];
1067
- if (!contractAddress) {
1068
- throw new Error(
1069
- `Contract address not found for ${contract} on chain ${chainId}`
1070
- );
872
+ // src/utils/transactionParsing.ts
873
+ import { parseEventLogs } from "viem";
874
+
875
+ // src/config/eventMappings.ts
876
+ var EVENT_MAPPINGS = {
877
+ // Permission operations
878
+ grant: {
879
+ contract: "DataPermissions",
880
+ event: "PermissionAdded"
881
+ },
882
+ revoke: {
883
+ contract: "DataPermissions",
884
+ event: "PermissionRevoked"
885
+ },
886
+ trustServer: {
887
+ contract: "DataPermissions",
888
+ event: "ServerTrusted"
889
+ },
890
+ untrustServer: {
891
+ contract: "DataPermissions",
892
+ event: "ServerUntrusted"
893
+ },
894
+ // Data registry operations
895
+ addFile: {
896
+ contract: "DataRegistry",
897
+ event: "FileAdded"
898
+ },
899
+ addRefinement: {
900
+ contract: "DataRegistry",
901
+ event: "RefinementAdded"
902
+ },
903
+ updateRefinement: {
904
+ contract: "DataRegistry",
905
+ event: "RefinementUpdated"
906
+ },
907
+ addFilePermission: {
908
+ contract: "DataRegistry",
909
+ event: "PermissionGranted"
1071
910
  }
1072
- return contractAddress;
1073
911
  };
1074
912
 
1075
913
  // src/abi/ComputeEngineImplementation.ts
@@ -33276,6 +33114,332 @@ function getAbi(contract) {
33276
33114
  return abi;
33277
33115
  }
33278
33116
 
33117
+ // src/utils/transactionParsing.ts
33118
+ async function parseTransactionResult(context, hash, operation) {
33119
+ const mapping = EVENT_MAPPINGS[operation];
33120
+ try {
33121
+ console.debug(`\u{1F50D} Parsing ${operation} transaction: ${hash}`);
33122
+ const receipt = await context.publicClient.waitForTransactionReceipt({
33123
+ hash,
33124
+ timeout: 3e4
33125
+ // 30 second timeout
33126
+ });
33127
+ console.debug(`\u2705 Transaction confirmed in block ${receipt.blockNumber}`);
33128
+ const abi = getAbi(mapping.contract);
33129
+ const events = parseEventLogs({
33130
+ logs: receipt.logs,
33131
+ abi,
33132
+ eventName: mapping.event,
33133
+ strict: true
33134
+ // Only return logs that conform to the ABI
33135
+ });
33136
+ if (events.length === 0) {
33137
+ throw new BlockchainError(
33138
+ `No ${mapping.event} event found in transaction ${hash}. Transaction may have failed or reverted.`
33139
+ );
33140
+ }
33141
+ if (events.length > 1) {
33142
+ console.warn(
33143
+ `\u26A0\uFE0F Multiple ${mapping.event} events found in transaction ${hash}. Using the first one.`
33144
+ );
33145
+ }
33146
+ const event = events[0];
33147
+ console.debug(`\u{1F389} Found ${mapping.event} event with args:`, event.args);
33148
+ return {
33149
+ ...event.args,
33150
+ transactionHash: hash,
33151
+ blockNumber: receipt.blockNumber,
33152
+ gasUsed: receipt.gasUsed
33153
+ };
33154
+ } catch (error) {
33155
+ if (error instanceof BlockchainError || error instanceof NetworkError) {
33156
+ throw error;
33157
+ }
33158
+ if (error instanceof Error && error.message.includes("timeout")) {
33159
+ throw new NetworkError(
33160
+ `Transaction ${hash} confirmation timeout after 30 seconds. The transaction may still be pending.`,
33161
+ error
33162
+ );
33163
+ }
33164
+ throw new BlockchainError(
33165
+ `Failed to parse ${operation} transaction ${hash}: ${error instanceof Error ? error.message : "Unknown error"}`,
33166
+ error
33167
+ );
33168
+ }
33169
+ }
33170
+
33171
+ // src/config/addresses.ts
33172
+ var CONTRACTS = {
33173
+ // Core Platform Contracts
33174
+ DataPermissions: {
33175
+ addresses: {
33176
+ 14800: "0x31fb1D48f6B2265A4cAD516BC39E96a18fb7c8de",
33177
+ 1480: "0x31fb1D48f6B2265A4cAD516BC39E96a18fb7c8de"
33178
+ }
33179
+ },
33180
+ DataRegistry: {
33181
+ addresses: {
33182
+ 14800: "0x8C8788f98385F6ba1adD4234e551ABba0f82Cb7C",
33183
+ 1480: "0x8C8788f98385F6ba1adD4234e551ABba0f82Cb7C"
33184
+ }
33185
+ },
33186
+ TeePoolPhala: {
33187
+ addresses: {
33188
+ 14800: "0xE8EC6BD73b23Ad40E6B9a6f4bD343FAc411bD99A",
33189
+ 1480: "0xE8EC6BD73b23Ad40E6B9a6f4bD343FAc411bD99A"
33190
+ }
33191
+ },
33192
+ ComputeEngine: {
33193
+ addresses: {
33194
+ 14800: "0xb2BFe33FA420c45F1Cf1287542ad81ae935447bd",
33195
+ 1480: "0xb2BFe33FA420c45F1Cf1287542ad81ae935447bd"
33196
+ }
33197
+ },
33198
+ // Data Access Infrastructure
33199
+ DataRefinerRegistry: {
33200
+ addresses: {
33201
+ 14800: "0x93c3EF89369fDcf08Be159D9DeF0F18AB6Be008c",
33202
+ 1480: "0x93c3EF89369fDcf08Be159D9DeF0F18AB6Be008c"
33203
+ }
33204
+ },
33205
+ QueryEngine: {
33206
+ addresses: {
33207
+ 14800: "0xd25Eb66EA2452cf3238A2eC6C1FD1B7F5B320490",
33208
+ 1480: "0xd25Eb66EA2452cf3238A2eC6C1FD1B7F5B320490"
33209
+ }
33210
+ },
33211
+ VanaTreasury: {
33212
+ addresses: {
33213
+ 14800: "0x94a1E56e555ac48d092f490fB10CDFaB434915eD",
33214
+ 1480: "0x94a1E56e555ac48d092f490fB10CDFaB434915eD"
33215
+ }
33216
+ },
33217
+ ComputeInstructionRegistry: {
33218
+ addresses: {
33219
+ 14800: "0x5786B12b4c6Ba2bFAF0e77Ed30Bf6d32805563A5",
33220
+ 1480: "0x5786B12b4c6Ba2bFAF0e77Ed30Bf6d32805563A5"
33221
+ }
33222
+ },
33223
+ // TEE Pool Variants
33224
+ TeePoolEphemeralStandard: {
33225
+ addresses: {
33226
+ 14800: "0xe124bae846D5ec157f75Bd9e68ca87C4d2AB835A",
33227
+ 1480: "0xe124bae846D5ec157f75Bd9e68ca87C4d2AB835A"
33228
+ }
33229
+ },
33230
+ TeePoolPersistentStandard: {
33231
+ addresses: {
33232
+ 14800: "0xe8bB8d0629651Cf33e0845d743976Dc1f0971d76",
33233
+ 1480: "0xe8bB8d0629651Cf33e0845d743976Dc1f0971d76"
33234
+ }
33235
+ },
33236
+ TeePoolPersistentGpu: {
33237
+ addresses: {
33238
+ 14800: "0x1c346Cd74f8551f8fa13f3F4b6b8dAE22338E6a9",
33239
+ 1480: "0x1c346Cd74f8551f8fa13f3F4b6b8dAE22338E6a9"
33240
+ }
33241
+ },
33242
+ TeePoolDedicatedStandard: {
33243
+ addresses: {
33244
+ 14800: "0xf024b7ac5E8417416f53B41ecfa58C8e9396687d",
33245
+ 1480: "0xf024b7ac5E8417416f53B41ecfa58C8e9396687d"
33246
+ }
33247
+ },
33248
+ TeePoolDedicatedGpu: {
33249
+ addresses: {
33250
+ 14800: "0xB1686FA9620bBf851714d1cB47b8a4Bf4664644E",
33251
+ 1480: "0xB1686FA9620bBf851714d1cB47b8a4Bf4664644E"
33252
+ }
33253
+ },
33254
+ // DLP Reward System
33255
+ VanaEpoch: {
33256
+ addresses: {
33257
+ 14800: "0x2063cFF0609D59bCCc196E20Eb58A8696a6b15A0",
33258
+ 1480: "0x2063cFF0609D59bCCc196E20Eb58A8696a6b15A0"
33259
+ }
33260
+ },
33261
+ DLPRegistry: {
33262
+ addresses: {
33263
+ 14800: "0x4D59880a924526d1dD33260552Ff4328b1E18a43",
33264
+ 1480: "0x4D59880a924526d1dD33260552Ff4328b1E18a43"
33265
+ }
33266
+ },
33267
+ DLPRegistryTreasury: {
33268
+ addresses: {
33269
+ 14800: "0xb12ce1d27bEeFe39b6F0110b1AB77C21Aa0c9F9a",
33270
+ 1480: "0xb12ce1d27bEeFe39b6F0110b1AB77C21Aa0c9F9a"
33271
+ }
33272
+ },
33273
+ DLPPerformance: {
33274
+ addresses: {
33275
+ 14800: "0x847715C7DB37cF286611182Be0bD333cbfa29cc1",
33276
+ 1480: "0x847715C7DB37cF286611182Be0bD333cbfa29cc1"
33277
+ }
33278
+ },
33279
+ DLPRewardDeployer: {
33280
+ addresses: {
33281
+ 14800: "0xEFD0F9Ba9De70586b7c4189971cF754adC923B04",
33282
+ 1480: "0xEFD0F9Ba9De70586b7c4189971cF754adC923B04"
33283
+ }
33284
+ },
33285
+ DLPRewardDeployerTreasury: {
33286
+ addresses: {
33287
+ 14800: "0xb547ca8Fe4990fe330FeAeb1C2EBb42F925Af5b8",
33288
+ 1480: "0xb547ca8Fe4990fe330FeAeb1C2EBb42F925Af5b8"
33289
+ }
33290
+ },
33291
+ DLPRewardSwap: {
33292
+ addresses: {
33293
+ 14800: "0x7c6862C46830F0fc3bF3FF509EA1bD0EE7267fB0",
33294
+ 1480: "0x7c6862C46830F0fc3bF3FF509EA1bD0EE7267fB0"
33295
+ }
33296
+ },
33297
+ SwapHelper: {
33298
+ addresses: {
33299
+ 14800: "0x55D5e6F73326315bF2E091e97F04f0770e5C54e2",
33300
+ 1480: "0x55D5e6F73326315bF2E091e97F04f0770e5C54e2"
33301
+ }
33302
+ },
33303
+ // VanaPool (Staking)
33304
+ VanaPoolStaking: {
33305
+ addresses: {
33306
+ 14800: "0x641C18E2F286c86f96CE95C8ec1EB9fC0415Ca0e",
33307
+ 1480: "0x641C18E2F286c86f96CE95C8ec1EB9fC0415Ca0e"
33308
+ }
33309
+ },
33310
+ VanaPoolEntity: {
33311
+ addresses: {
33312
+ 14800: "0x44f20490A82e1f1F1cC25Dd3BA8647034eDdce30",
33313
+ 1480: "0x44f20490A82e1f1F1cC25Dd3BA8647034eDdce30"
33314
+ }
33315
+ },
33316
+ VanaPoolTreasury: {
33317
+ addresses: {
33318
+ 14800: "0x143BE72CF2541604A7691933CAccd6D9cC17c003",
33319
+ 1480: "0x143BE72CF2541604A7691933CAccd6D9cC17c003"
33320
+ }
33321
+ },
33322
+ // DLP Deployment Contracts
33323
+ DAT: {
33324
+ addresses: {
33325
+ 14800: "0xA706b93ccED89f13340673889e29F0a5cd84212d",
33326
+ 1480: "0xA706b93ccED89f13340673889e29F0a5cd84212d"
33327
+ }
33328
+ },
33329
+ DATFactory: {
33330
+ addresses: {
33331
+ 14800: "0x40f8bccF35a75ecef63BC3B1B3E06ffEB9220644",
33332
+ 1480: "0x40f8bccF35a75ecef63BC3B1B3E06ffEB9220644"
33333
+ }
33334
+ },
33335
+ DATPausable: {
33336
+ addresses: {
33337
+ 14800: "0xe69FE86f0B95cC2f8416Fe22815c85DC8887e76e",
33338
+ 1480: "0xe69FE86f0B95cC2f8416Fe22815c85DC8887e76e"
33339
+ }
33340
+ },
33341
+ DATVotes: {
33342
+ addresses: {
33343
+ 14800: "0xaE04c8A77E9B27869eb563720524A9aE0baf1831",
33344
+ 1480: "0xaE04c8A77E9B27869eb563720524A9aE0baf1831"
33345
+ }
33346
+ },
33347
+ // Utility Contracts (no ABIs in SDK)
33348
+ Multicall3: {
33349
+ addresses: {
33350
+ 14800: "0xD8d2dFca27E8797fd779F8547166A2d3B29d360E",
33351
+ 1480: "0xD8d2dFca27E8797fd779F8547166A2d3B29d360E"
33352
+ }
33353
+ },
33354
+ Multisend: {
33355
+ addresses: {
33356
+ 14800: "0x8807e8BCDFbaA8c2761760f3FBA37F6f7F2C5b2d",
33357
+ 1480: "0x8807e8BCDFbaA8c2761760f3FBA37F6f7F2C5b2d"
33358
+ }
33359
+ }
33360
+ };
33361
+ var LEGACY_CONTRACTS = {
33362
+ // DEPRECATED: Original Intel SGX TeePool (PRO-347)
33363
+ TeePool: {
33364
+ addresses: {
33365
+ 14800: "0x3c92fD91639b41f13338CE62f19131e7d19eaa0D",
33366
+ 1480: "0x3c92fD91639b41f13338CE62f19131e7d19eaa0D"
33367
+ }
33368
+ },
33369
+ // DEPRECATED: DLPRoot system (replaced by VanaPool + DLPRewards)
33370
+ DLPRootEpoch: {
33371
+ addresses: {
33372
+ 14800: "0xc3d176cF6BccFCB9225b53B87a95147218e1537F",
33373
+ 1480: "0xc3d176cF6BccFCB9225b53B87a95147218e1537F"
33374
+ }
33375
+ },
33376
+ DLPRootCore: {
33377
+ addresses: {
33378
+ 14800: "0x0aBa5e28228c323A67712101d61a54d4ff5720FD",
33379
+ 1480: "0x0aBa5e28228c323A67712101d61a54d4ff5720FD"
33380
+ }
33381
+ },
33382
+ DLPRoot: {
33383
+ addresses: {
33384
+ 14800: "0xff14346dF2B8Fd0c95BF34f1c92e49417b508AD5",
33385
+ 1480: "0xff14346dF2B8Fd0c95BF34f1c92e49417b508AD5"
33386
+ }
33387
+ },
33388
+ DLPRootMetrics: {
33389
+ addresses: {
33390
+ 14800: "0xbb532917B6407c060Afd9Cb7d53527eCb91d6662",
33391
+ 1480: "0xbb532917B6407c060Afd9Cb7d53527eCb91d6662"
33392
+ }
33393
+ },
33394
+ DLPRootStakesTreasury: {
33395
+ addresses: {
33396
+ 14800: "0x52c3260ED5C235fcA43524CF508e29c897318775",
33397
+ 1480: "0x52c3260ED5C235fcA43524CF508e29c897318775"
33398
+ }
33399
+ },
33400
+ DLPRootRewardsTreasury: {
33401
+ addresses: {
33402
+ 14800: "0xDBFb6B8b9E2eCAEbdE64d665cD553dB81e524479",
33403
+ 1480: "0xDBFb6B8b9E2eCAEbdE64d665cD553dB81e524479"
33404
+ }
33405
+ }
33406
+ };
33407
+ var CONTRACT_ADDRESSES = {
33408
+ 14800: Object.fromEntries(
33409
+ Object.entries(CONTRACTS).map(([name, info]) => [name, info.addresses[14800]]).filter(([, addr]) => addr)
33410
+ ),
33411
+ 1480: Object.fromEntries(
33412
+ Object.entries(CONTRACTS).map(([name, info]) => [name, info.addresses[1480]]).filter(([, addr]) => addr)
33413
+ )
33414
+ };
33415
+ var UTILITY_ADDRESSES = {
33416
+ 14800: {
33417
+ Multicall3: CONTRACTS.Multicall3.addresses[14800],
33418
+ Multisend: CONTRACTS.Multisend.addresses[14800]
33419
+ },
33420
+ 1480: {
33421
+ Multicall3: CONTRACTS.Multicall3.addresses[1480],
33422
+ Multisend: CONTRACTS.Multisend.addresses[1480]
33423
+ }
33424
+ };
33425
+ var LEGACY_ADDRESSES = {
33426
+ 14800: Object.fromEntries(
33427
+ Object.entries(LEGACY_CONTRACTS).map(([name, info]) => [name, info.addresses[14800]]).filter(([, addr]) => addr)
33428
+ ),
33429
+ 1480: Object.fromEntries(
33430
+ Object.entries(LEGACY_CONTRACTS).map(([name, info]) => [name, info.addresses[1480]]).filter(([, addr]) => addr)
33431
+ )
33432
+ };
33433
+ var getContractAddress = (chainId, contract) => {
33434
+ const contractAddress = CONTRACT_ADDRESSES[chainId]?.[contract];
33435
+ if (!contractAddress) {
33436
+ throw new Error(
33437
+ `Contract address not found for ${contract} on chain ${chainId}`
33438
+ );
33439
+ }
33440
+ return contractAddress;
33441
+ };
33442
+
33279
33443
  // src/utils/grantFiles.ts
33280
33444
  import { keccak256, toHex } from "viem";
33281
33445
  function createGrantFile(params) {
@@ -33677,6 +33841,158 @@ function validateOperationAccess(grantFile, requestedOperation) {
33677
33841
  }
33678
33842
  }
33679
33843
 
33844
+ // src/utils/signatureCache.ts
33845
+ init_crypto_utils();
33846
+ var SignatureCache = class {
33847
+ /**
33848
+ * Get a cached signature if it exists and hasn't expired
33849
+ *
33850
+ * @param cache - Platform cache adapter instance
33851
+ * @param walletAddress - Wallet address that created the signature
33852
+ * @param messageHash - Hash of the message that was signed
33853
+ * @returns The cached signature if valid, null if expired or not found
33854
+ * @example
33855
+ * ```typescript
33856
+ * const messageHash = SignatureCache.hashMessage(typedData);
33857
+ * const cached = SignatureCache.get(cache, '0x123...', messageHash);
33858
+ * if (cached) {
33859
+ * console.log('Using cached signature:', cached);
33860
+ * }
33861
+ * ```
33862
+ */
33863
+ static get(cache, walletAddress, messageHash) {
33864
+ const key = this.getCacheKey(walletAddress, messageHash);
33865
+ try {
33866
+ const stored = cache.get(key);
33867
+ if (!stored) return null;
33868
+ const cached = JSON.parse(stored);
33869
+ if (Date.now() > cached.expires) {
33870
+ cache.delete(key);
33871
+ return null;
33872
+ }
33873
+ return cached.signature;
33874
+ } catch {
33875
+ try {
33876
+ cache.delete(key);
33877
+ } catch {
33878
+ }
33879
+ return null;
33880
+ }
33881
+ }
33882
+ /**
33883
+ * Store a signature in the cache with configurable TTL
33884
+ *
33885
+ * @param cache - Platform cache adapter instance
33886
+ * @param walletAddress - Wallet address that created the signature
33887
+ * @param messageHash - Hash of the message that was signed
33888
+ * @param signature - The signature to cache
33889
+ * @param ttlHours - Time to live in hours (default: 2)
33890
+ * @example
33891
+ * ```typescript
33892
+ * const signature = await wallet.signTypedData(typedData);
33893
+ * const messageHash = SignatureCache.hashMessage(typedData);
33894
+ *
33895
+ * // Cache for default 2 hours
33896
+ * SignatureCache.set(cache, walletAddress, messageHash, signature);
33897
+ *
33898
+ * // Cache for 24 hours
33899
+ * SignatureCache.set(cache, walletAddress, messageHash, signature, 24);
33900
+ * ```
33901
+ */
33902
+ static set(cache, walletAddress, messageHash, signature, ttlHours = this.DEFAULT_TTL_HOURS) {
33903
+ const key = this.getCacheKey(walletAddress, messageHash);
33904
+ const cached = {
33905
+ signature,
33906
+ expires: Date.now() + ttlHours * 36e5
33907
+ // Convert hours to milliseconds
33908
+ };
33909
+ try {
33910
+ cache.set(key, JSON.stringify(cached));
33911
+ } catch {
33912
+ }
33913
+ }
33914
+ /**
33915
+ * Clear all cached signatures (useful for testing or explicit cleanup)
33916
+ *
33917
+ * @param cache - Platform cache adapter instance
33918
+ * @example
33919
+ * ```typescript
33920
+ * // Clear all signatures when user logs out
33921
+ * SignatureCache.clear(cache);
33922
+ *
33923
+ * // Clear before running tests
33924
+ * beforeEach(() => {
33925
+ * SignatureCache.clear(cache);
33926
+ * });
33927
+ * ```
33928
+ */
33929
+ static clear(cache) {
33930
+ try {
33931
+ cache.clear();
33932
+ } catch {
33933
+ }
33934
+ }
33935
+ static getCacheKey(walletAddress, messageHash) {
33936
+ return `${this.PREFIX}${walletAddress.toLowerCase()}:${messageHash}`;
33937
+ }
33938
+ /**
33939
+ * Generate a deterministic hash of a message object for cache key generation
33940
+ *
33941
+ * @remarks
33942
+ * Creates a consistent hash from complex objects including EIP-712 typed data.
33943
+ * Handles BigInt serialization and produces a 32-character hash that balances
33944
+ * uniqueness with key length constraints.
33945
+ *
33946
+ * @param message - The message object to hash (typically EIP-712 typed data)
33947
+ * @returns A 32-character hash string suitable for cache keys
33948
+ * @example
33949
+ * ```typescript
33950
+ * const typedData = {
33951
+ * domain: { name: 'Vana', version: '1' },
33952
+ * message: { nonce: 123n, grant: '...' }
33953
+ * };
33954
+ *
33955
+ * const hash = SignatureCache.hashMessage(typedData);
33956
+ * // Returns something like: "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
33957
+ * ```
33958
+ */
33959
+ static hashMessage(message) {
33960
+ const jsonString = JSON.stringify(message, this.bigIntReplacer);
33961
+ const base64Hash = toBase64(jsonString);
33962
+ const cleaned = base64Hash.replace(/[^a-zA-Z0-9]/g, "");
33963
+ if (cleaned.length > 32) {
33964
+ return cleaned.substring(0, 16) + cleaned.substring(cleaned.length - 16);
33965
+ }
33966
+ return cleaned.substring(0, 32);
33967
+ }
33968
+ /**
33969
+ * Custom JSON replacer that converts BigInt values to strings for serialization
33970
+ * This ensures deterministic cache key generation for EIP-712 typed data
33971
+ *
33972
+ * @param _key - The object key being serialized (unused)
33973
+ * @param value - The value to serialize
33974
+ * @returns The serialized value
33975
+ */
33976
+ static bigIntReplacer(_key, value) {
33977
+ if (typeof value === "bigint") {
33978
+ return `__BIGINT__${value.toString()}`;
33979
+ }
33980
+ return value;
33981
+ }
33982
+ };
33983
+ __publicField(SignatureCache, "PREFIX", "vana_sig_");
33984
+ __publicField(SignatureCache, "DEFAULT_TTL_HOURS", 2);
33985
+ async function withSignatureCache(cache, walletAddress, typedData, signFn, ttlHours) {
33986
+ const messageHash = SignatureCache.hashMessage(typedData);
33987
+ const cached = SignatureCache.get(cache, walletAddress, messageHash);
33988
+ if (cached) {
33989
+ return cached;
33990
+ }
33991
+ const signature = await signFn();
33992
+ SignatureCache.set(cache, walletAddress, messageHash, signature, ttlHours);
33993
+ return signature;
33994
+ }
33995
+
33680
33996
  // src/controllers/permissions.ts
33681
33997
  var PermissionsController = class {
33682
33998
  constructor(context) {
@@ -33685,21 +34001,21 @@ var PermissionsController = class {
33685
34001
  /**
33686
34002
  * Grants permission for an application to access user data with gasless transactions.
33687
34003
  *
33688
- * @remarks
33689
- * This method combines signature creation and gasless submission for a complete
33690
- * end-to-end permission grant flow. It creates the grant file, stores it on IPFS,
33691
- * generates an EIP-712 signature, and submits via relayer. The grant file contains
33692
- * detailed parameters while the blockchain stores only a reference to enable
33693
- * efficient permission queries.
34004
+ * This method provides a complete end-to-end permission grant flow that returns
34005
+ * the permission ID and other relevant data immediately after successful submission.
34006
+ * For advanced users who need more control over the transaction lifecycle, use
34007
+ * `submitPermissionGrant()` instead.
34008
+ *
33694
34009
  * @param params - The permission grant configuration object
33695
- * @returns A Promise that resolves to the transaction hash when successfully submitted
34010
+ * @returns Promise resolving to permission data from the PermissionAdded event
33696
34011
  * @throws {RelayerError} When gasless transaction submission fails
33697
34012
  * @throws {SignatureError} When user rejects the signature request
33698
34013
  * @throws {SerializationError} When grant data cannot be serialized
33699
- * @throws {BlockchainError} When permission grant preparation fails
34014
+ * @throws {BlockchainError} When permission grant fails or event parsing fails
34015
+ * @throws {NetworkError} When transaction confirmation times out
33700
34016
  * @example
33701
34017
  * ```typescript
33702
- * const txHash = await vana.permissions.grant({
34018
+ * const result = await vana.permissions.grant({
33703
34019
  * grantee: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36",
33704
34020
  * operation: "llm_inference",
33705
34021
  * parameters: {
@@ -33709,10 +34025,42 @@ var PermissionsController = class {
33709
34025
  * },
33710
34026
  * });
33711
34027
  *
33712
- * console.log(`Permission granted: ${txHash}`);
34028
+ * console.log(`Permission ${result.permissionId} granted to ${result.user}`);
34029
+ * console.log(`Transaction: ${result.transactionHash}`);
34030
+ *
34031
+ * // Can immediately use the permission ID for other operations
34032
+ * await vana.permissions.revoke({ permissionId: result.permissionId });
33713
34033
  * ```
33714
34034
  */
33715
34035
  async grant(params) {
34036
+ const txHash = await this.submitPermissionGrant(params);
34037
+ return parseTransactionResult(this.context, txHash, "grant");
34038
+ }
34039
+ /**
34040
+ * Submits a permission grant transaction and returns the transaction hash immediately.
34041
+ *
34042
+ * This is the lower-level method that provides maximum control over transaction timing.
34043
+ * Use this when you want to handle transaction confirmation and event parsing separately,
34044
+ * or when submitting multiple transactions in batch.
34045
+ *
34046
+ * @param params - The permission grant configuration object
34047
+ * @returns Promise that resolves to the transaction hash when successfully submitted
34048
+ * @throws {RelayerError} When gasless transaction submission fails
34049
+ * @throws {SignatureError} When user rejects the signature request
34050
+ * @throws {SerializationError} When grant data cannot be serialized
34051
+ * @throws {BlockchainError} When permission grant preparation fails
34052
+ * @example
34053
+ * ```typescript
34054
+ * // Submit transaction and handle confirmation later
34055
+ * const txHash = await vana.permissions.submitPermissionGrant(params);
34056
+ * console.log(`Transaction submitted: ${txHash}`);
34057
+ *
34058
+ * // Later, when you need the permission data:
34059
+ * const result = await parseTransactionResult(context, txHash, 'grant');
34060
+ * console.log(`Permission ID: ${result.permissionId}`);
34061
+ * ```
34062
+ */
34063
+ async submitPermissionGrant(params) {
33716
34064
  const { typedData, signature } = await this.createAndSign(params);
33717
34065
  return await this.submitSignedGrant(typedData, signature);
33718
34066
  }
@@ -33726,6 +34074,8 @@ var PermissionsController = class {
33726
34074
  * until the returned `confirm()` function is called.
33727
34075
  * @param params - The permission grant parameters
33728
34076
  * @returns A promise resolving to a preview object and confirm function
34077
+ * @throws {SerializationError} When grant parameters are invalid or cannot be serialized
34078
+ * @throws {BlockchainError} When grant validation fails or preparation encounters an error
33729
34079
  * @example
33730
34080
  * ```typescript
33731
34081
  * const { preview, confirm } = await vana.permissions.prepareGrant({
@@ -34130,22 +34480,51 @@ var PermissionsController = class {
34130
34480
  /**
34131
34481
  * Revokes a previously granted permission.
34132
34482
  *
34483
+ * This method provides complete revocation with automatic event parsing to confirm
34484
+ * the permission was successfully revoked. For advanced users who need more control,
34485
+ * use `submitPermissionRevoke()` instead.
34486
+ *
34133
34487
  * @param params - Parameters for revoking the permission
34134
- * @returns Promise resolving to transaction hash
34488
+ * @param params.permissionId - Permission identifier (accepts bigint, number, or string).
34489
+ * Obtain from permission grants via `getUserPermissionGrantsOnChain()`.
34490
+ * @returns Promise resolving to revocation data from PermissionRevoked event
34491
+ * @throws {BlockchainError} When revocation fails or event parsing fails
34492
+ * @throws {UserRejectedRequestError} When user rejects the transaction
34493
+ * @throws {NetworkError} When transaction confirmation times out
34135
34494
  * @example
34136
34495
  * ```typescript
34137
- * // Revoke a permission by its ID
34138
- * const txHash = await vana.permissions.revoke({
34496
+ * // Revoke a permission and get confirmation
34497
+ * const result = await vana.permissions.revoke({
34139
34498
  * permissionId: 123n
34140
34499
  * });
34141
- * console.log('Permission revoked in transaction:', txHash);
34142
- *
34143
- * // Wait for confirmation if needed
34144
- * const receipt = await vana.core.waitForTransaction(txHash);
34145
- * console.log('Revocation confirmed in block:', receipt.blockNumber);
34500
+ * console.log(`Permission ${result.permissionId} revoked in transaction ${result.transactionHash}`);
34501
+ * console.log(`Revoked in block ${result.blockNumber}`);
34146
34502
  * ```
34147
34503
  */
34148
34504
  async revoke(params) {
34505
+ const txHash = await this.submitPermissionRevoke(params);
34506
+ return parseTransactionResult(this.context, txHash, "revoke");
34507
+ }
34508
+ /**
34509
+ * Submits a permission revocation transaction and returns the transaction hash immediately.
34510
+ *
34511
+ * This is the lower-level method that provides maximum control over transaction timing.
34512
+ * Use this when you want to handle transaction confirmation and event parsing separately.
34513
+ *
34514
+ * @param params - Parameters for revoking the permission
34515
+ * @returns Promise resolving to the transaction hash when successfully submitted
34516
+ * @throws {BlockchainError} When revocation transaction fails
34517
+ * @throws {UserRejectedRequestError} When user rejects the transaction
34518
+ * @example
34519
+ * ```typescript
34520
+ * // Submit revocation and handle confirmation later
34521
+ * const txHash = await vana.permissions.submitPermissionRevoke({
34522
+ * permissionId: 123n
34523
+ * });
34524
+ * console.log(`Revocation submitted: ${txHash}`);
34525
+ * ```
34526
+ */
34527
+ async submitPermissionRevoke(params) {
34149
34528
  try {
34150
34529
  if (!this.context.walletClient.chain?.id) {
34151
34530
  throw new BlockchainError("Chain ID not available");
@@ -34183,6 +34562,11 @@ var PermissionsController = class {
34183
34562
  *
34184
34563
  * @param params - Parameters for revoking the permission
34185
34564
  * @returns Promise resolving to transaction hash
34565
+ * @throws {BlockchainError} When chain ID is not available
34566
+ * @throws {NonceError} When retrieving user nonce fails
34567
+ * @throws {SignatureError} When user rejects the signature request
34568
+ * @throws {RelayerError} When gasless submission fails
34569
+ * @throws {PermissionError} When revocation fails for any other reason
34186
34570
  */
34187
34571
  async revokeWithSignature(params) {
34188
34572
  try {
@@ -34225,6 +34609,9 @@ var PermissionsController = class {
34225
34609
  * Retrieves the user's current nonce from the DataPermissions contract.
34226
34610
  *
34227
34611
  * @returns Promise resolving to the user's current nonce value
34612
+ * @throws {Error} When wallet account is not available
34613
+ * @throws {Error} When chain ID is not available
34614
+ * @throws {NonceError} When reading nonce from contract fails
34228
34615
  */
34229
34616
  async getUserNonce() {
34230
34617
  try {
@@ -34311,17 +34698,24 @@ var PermissionsController = class {
34311
34698
  };
34312
34699
  }
34313
34700
  /**
34314
- * Signs typed data using the wallet client.
34701
+ * Signs typed data using the wallet client with signature caching.
34315
34702
  *
34316
34703
  * @param typedData - The EIP-712 typed data structure to sign
34317
34704
  * @returns Promise resolving to the cryptographic signature
34318
34705
  */
34319
34706
  async signTypedData(typedData) {
34320
34707
  try {
34321
- const signature = await this.context.walletClient.signTypedData(
34322
- typedData
34708
+ const walletAddress = this.context.walletClient.account?.address || await this.getUserAddress();
34709
+ return await withSignatureCache(
34710
+ this.context.platform.cache,
34711
+ walletAddress,
34712
+ typedData,
34713
+ async () => {
34714
+ return await this.context.walletClient.signTypedData(
34715
+ typedData
34716
+ );
34717
+ }
34323
34718
  );
34324
- return signature;
34325
34719
  } catch (error) {
34326
34720
  if (error instanceof Error && error.message.includes("rejected")) {
34327
34721
  throw new UserRejectedRequestError();
@@ -34464,6 +34858,7 @@ var PermissionsController = class {
34464
34858
  *
34465
34859
  * @param fileId - The file ID to query permissions for
34466
34860
  * @returns Promise resolving to array of permission IDs
34861
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
34467
34862
  */
34468
34863
  async getFilePermissionIds(fileId) {
34469
34864
  try {
@@ -34492,6 +34887,7 @@ var PermissionsController = class {
34492
34887
  *
34493
34888
  * @param permissionId - The permission ID to query files for
34494
34889
  * @returns Promise resolving to array of file IDs
34890
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
34495
34891
  */
34496
34892
  async getPermissionFileIds(permissionId) {
34497
34893
  try {
@@ -34520,6 +34916,7 @@ var PermissionsController = class {
34520
34916
  *
34521
34917
  * @param permissionId - The permission ID to check
34522
34918
  * @returns Promise resolving to boolean indicating if permission is active
34919
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
34523
34920
  */
34524
34921
  async isActivePermission(permissionId) {
34525
34922
  try {
@@ -34548,6 +34945,7 @@ var PermissionsController = class {
34548
34945
  *
34549
34946
  * @param permissionId - The permission ID to query
34550
34947
  * @returns Promise resolving to permission info
34948
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
34551
34949
  */
34552
34950
  async getPermissionInfo(permissionId) {
34553
34951
  try {
@@ -34595,13 +34993,18 @@ var PermissionsController = class {
34595
34993
  * Trusts a server for data processing.
34596
34994
  *
34597
34995
  * @param params - Parameters for trusting the server
34996
+ * @param params.serverId - The server's Ethereum address
34997
+ * @param params.serverUrl - The server's URL endpoint
34598
34998
  * @returns Promise resolving to transaction hash
34999
+ * @throws {UserRejectedRequestError} When user rejects the transaction
35000
+ * @throws {BlockchainError} When chain ID is unavailable or transaction fails
35001
+ * @throws {Error} When wallet account is not available
34599
35002
  * @example
34600
35003
  * ```typescript
34601
35004
  * // Trust a server by providing its ID and URL
34602
35005
  * const txHash = await vana.permissions.trustServer({
34603
35006
  * serverId: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
34604
- * serverUrl: 'https://myserver.example.com'
35007
+ * serverUrl: 'https://personal-server.vana.org'
34605
35008
  * });
34606
35009
  * console.log('Server trusted in transaction:', txHash);
34607
35010
  *
@@ -34642,6 +35045,12 @@ var PermissionsController = class {
34642
35045
  *
34643
35046
  * @param params - Parameters for trusting the server
34644
35047
  * @returns Promise resolving to transaction hash
35048
+ * @throws {BlockchainError} When chain ID is not available
35049
+ * @throws {NonceError} When retrieving user nonce fails
35050
+ * @throws {SignatureError} When user rejects the signature request
35051
+ * @throws {RelayerError} When gasless submission fails
35052
+ * @throws {ServerUrlMismatchError} When server URL doesn't match existing registration
35053
+ * @throws {BlockchainError} When trust operation fails for any other reason
34645
35054
  */
34646
35055
  async trustServerWithSignature(params) {
34647
35056
  try {
@@ -34716,7 +35125,12 @@ var PermissionsController = class {
34716
35125
  * Untrusts a server.
34717
35126
  *
34718
35127
  * @param params - Parameters for untrusting the server
35128
+ * @param params.serverId - The server's Ethereum address to untrust
34719
35129
  * @returns Promise resolving to transaction hash
35130
+ * @throws {Error} When wallet account is not available
35131
+ * @throws {NonceError} When retrieving user nonce fails
35132
+ * @throws {UserRejectedRequestError} When user rejects the transaction
35133
+ * @throws {BlockchainError} When untrust transaction fails
34720
35134
  */
34721
35135
  async untrustServer(params) {
34722
35136
  const nonce = await this.getUserNonce();
@@ -34730,7 +35144,13 @@ var PermissionsController = class {
34730
35144
  * Untrusts a server using a signature (gasless transaction).
34731
35145
  *
34732
35146
  * @param params - Parameters for untrusting the server
35147
+ * @param params.serverId - The server's Ethereum address to untrust
34733
35148
  * @returns Promise resolving to transaction hash
35149
+ * @throws {Error} When wallet account is not available
35150
+ * @throws {NonceError} When retrieving user nonce fails
35151
+ * @throws {SignatureError} When user rejects the signature request
35152
+ * @throws {RelayerError} When gasless submission fails
35153
+ * @throws {BlockchainError} When untrust transaction fails
34734
35154
  */
34735
35155
  async untrustServerWithSignature(params) {
34736
35156
  try {
@@ -34772,6 +35192,7 @@ var PermissionsController = class {
34772
35192
  *
34773
35193
  * @param userAddress - Optional user address (defaults to current user)
34774
35194
  * @returns Promise resolving to array of trusted server addresses
35195
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
34775
35196
  */
34776
35197
  async getTrustedServers(userAddress) {
34777
35198
  try {
@@ -34801,6 +35222,7 @@ var PermissionsController = class {
34801
35222
  *
34802
35223
  * @param serverId - Server address
34803
35224
  * @returns Promise resolving to server information
35225
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
34804
35226
  */
34805
35227
  async getServerInfo(serverId) {
34806
35228
  try {
@@ -34829,6 +35251,7 @@ var PermissionsController = class {
34829
35251
  *
34830
35252
  * @param userAddress - Optional user address (defaults to current user)
34831
35253
  * @returns Promise resolving to the number of trusted servers
35254
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
34832
35255
  */
34833
35256
  async getTrustedServersCount(userAddress) {
34834
35257
  try {
@@ -34858,6 +35281,7 @@ var PermissionsController = class {
34858
35281
  *
34859
35282
  * @param options - Query options including pagination parameters
34860
35283
  * @returns Promise resolving to paginated trusted servers
35284
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
34861
35285
  */
34862
35286
  async getTrustedServersPaginated(options = {}) {
34863
35287
  try {
@@ -34917,6 +35341,7 @@ var PermissionsController = class {
34917
35341
  *
34918
35342
  * @param options - Query options
34919
35343
  * @returns Promise resolving to array of trusted server info
35344
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
34920
35345
  */
34921
35346
  async getTrustedServersWithInfo(options = {}) {
34922
35347
  try {
@@ -34954,6 +35379,7 @@ var PermissionsController = class {
34954
35379
  *
34955
35380
  * @param serverIds - Array of server IDs to query
34956
35381
  * @returns Promise resolving to batch result with successes and failures
35382
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
34957
35383
  */
34958
35384
  async getServerInfoBatch(serverIds) {
34959
35385
  if (serverIds.length === 0) {
@@ -35155,15 +35581,22 @@ import { getContract, decodeEventLog } from "viem";
35155
35581
 
35156
35582
  // src/utils/encryption.ts
35157
35583
  var DEFAULT_ENCRYPTION_SEED = "Please sign to retrieve your encryption key";
35158
- async function generateEncryptionKey(wallet, seed = DEFAULT_ENCRYPTION_SEED) {
35584
+ async function generateEncryptionKey(wallet, platformAdapter, seed = DEFAULT_ENCRYPTION_SEED) {
35159
35585
  if (!wallet.account) {
35160
35586
  throw new Error("Wallet account is required for encryption key generation");
35161
35587
  }
35162
- const signature = await wallet.signMessage({
35163
- account: wallet.account,
35164
- message: seed
35165
- });
35166
- return signature;
35588
+ const messageData = { message: seed };
35589
+ return await withSignatureCache(
35590
+ platformAdapter.cache,
35591
+ wallet.account.address,
35592
+ messageData,
35593
+ async () => {
35594
+ return await wallet.signMessage({
35595
+ account: wallet.account,
35596
+ message: seed
35597
+ });
35598
+ }
35599
+ );
35167
35600
  }
35168
35601
  async function encryptWithWalletPublicKey(data, publicKey, platformAdapter) {
35169
35602
  try {
@@ -35328,6 +35761,7 @@ var DataController = class {
35328
35761
  if (encrypt2) {
35329
35762
  const encryptionKey = await generateEncryptionKey(
35330
35763
  this.context.walletClient,
35764
+ this.context.platform,
35331
35765
  DEFAULT_ENCRYPTION_SEED
35332
35766
  );
35333
35767
  finalBlob = await encryptBlobWithSignedKey(
@@ -35353,26 +35787,21 @@ var DataController = class {
35353
35787
  );
35354
35788
  const userAddress = owner || await this.getUserAddress();
35355
35789
  let encryptedPermissions = [];
35356
- if (permissions.length > 0 && encrypt2) {
35790
+ if (permissions.length > 0) {
35357
35791
  const userEncryptionKey = await generateEncryptionKey(
35358
35792
  this.context.walletClient,
35793
+ this.context.platform,
35359
35794
  DEFAULT_ENCRYPTION_SEED
35360
35795
  );
35361
35796
  encryptedPermissions = await Promise.all(
35362
35797
  permissions.map(async (permission) => {
35363
- const publicKey = permission.publicKey;
35364
- if (!publicKey) {
35365
- throw new Error(
35366
- `Public key required for permission to ${permission.grantee} when encryption is enabled`
35367
- );
35368
- }
35369
35798
  const encryptedKey = await encryptWithWalletPublicKey(
35370
35799
  userEncryptionKey,
35371
- publicKey,
35800
+ permission.publicKey,
35372
35801
  this.context.platform
35373
35802
  );
35374
35803
  return {
35375
- account: permission.grantee,
35804
+ account: permission.account,
35376
35805
  key: encryptedKey
35377
35806
  };
35378
35807
  })
@@ -35444,9 +35873,14 @@ var DataController = class {
35444
35873
  * @param file - The user file to decrypt (typically from getUserFiles)
35445
35874
  * @param encryptionSeed - Optional custom encryption seed (defaults to Vana standard)
35446
35875
  * @returns Promise resolving to the decrypted file content as a Blob
35447
- * @throws {Error} When the wallet is not connected
35448
- * @throws {Error} When fetching the encrypted content fails
35449
- * @throws {Error} When decryption fails (wrong key or corrupted data)
35876
+ * @throws {Error} "No addresses available in wallet client" - When wallet is not connected
35877
+ * @throws {Error} "Network error: Cannot access the file URL" - When file URL is inaccessible (CORS, server down)
35878
+ * @throws {Error} "File not found: The encrypted file is no longer available" - When file returns 404
35879
+ * @throws {Error} "Access denied" - When file returns 403 (no permission)
35880
+ * @throws {Error} "File is empty or could not be retrieved" - When file has no content
35881
+ * @throws {Error} "Invalid file format: This file doesn't appear to be encrypted with the Vana protocol" - When file is not properly encrypted
35882
+ * @throws {Error} "Wrong encryption key" - When decryption fails due to incorrect key/seed
35883
+ * @throws {Error} "Failed to decrypt file: {error}" - General decryption failures
35450
35884
  * @example
35451
35885
  * ```typescript
35452
35886
  * // Basic file decryption
@@ -35476,6 +35910,7 @@ var DataController = class {
35476
35910
  try {
35477
35911
  const encryptionKey = await generateEncryptionKey(
35478
35912
  this.context.walletClient,
35913
+ this.context.platform,
35479
35914
  encryptionSeed || DEFAULT_ENCRYPTION_SEED
35480
35915
  );
35481
35916
  let encryptedBlob;
@@ -35565,11 +36000,20 @@ var DataController = class {
35565
36000
  * This method queries the Vana subgraph to find files directly owned by the user.
35566
36001
  * It efficiently handles large datasets by using the File entity's owner field
35567
36002
  * and returns complete file metadata without additional contract calls.
36003
+ *
36004
+ * **Deduplication Behavior:**
36005
+ * The method automatically deduplicates files by ID, keeping only the latest version
36006
+ * (highest timestamp) when duplicate file IDs are found. This handles cases where
36007
+ * the subgraph may contain multiple entries for the same file due to re-indexing
36008
+ * or blockchain reorganizations.
35568
36009
  * @param params - The query parameters object
35569
36010
  * @param params.owner - The wallet address of the file owner to query
35570
36011
  * @param params.subgraphUrl - Optional subgraph URL to override the default endpoint
35571
- * @returns A Promise that resolves to an array of UserFile objects with metadata
35572
- * @throws {Error} When the subgraph is unavailable or returns invalid data
36012
+ * @returns A Promise that resolves to an array of UserFile objects with metadata, sorted by latest timestamp first
36013
+ * @throws {Error} When subgraphUrl is not provided and not configured - "subgraphUrl is required"
36014
+ * @throws {Error} When subgraph request fails - "Subgraph request failed: {status} {statusText}"
36015
+ * @throws {Error} When subgraph returns errors - "Subgraph errors: {error messages}"
36016
+ * @throws {Error} When JSON parsing fails - "Failed to fetch user files from subgraph: {error}"
35573
36017
  * @example
35574
36018
  * ```typescript
35575
36019
  * // Query files for a specific user
@@ -36072,6 +36516,9 @@ var DataController = class {
36072
36516
  *
36073
36517
  * @param fileId - The file ID to look up
36074
36518
  * @returns Promise resolving to UserFile object
36519
+ * @throws {Error} "Chain ID not available" - When wallet chain is not configured
36520
+ * @throws {Error} "File not found" - When file ID doesn't exist or returns empty data
36521
+ * @throws {Error} "Failed to fetch file {fileId}: {error}" - General contract read failures
36075
36522
  * @example
36076
36523
  * ```typescript
36077
36524
  * try {
@@ -36141,7 +36588,21 @@ var DataController = class {
36141
36588
  /**
36142
36589
  * Uploads an encrypted file to storage and registers it on the blockchain.
36143
36590
  *
36144
- * @deprecated Use vana.data.upload() instead for the high-level API with automatic encryption
36591
+ * @deprecated Since v2.0.0 - Use vana.data.upload() instead for the high-level API with automatic encryption
36592
+ *
36593
+ * Migration guide:
36594
+ * ```typescript
36595
+ * // Old way (deprecated):
36596
+ * const encrypted = await encryptBlob(data, key);
36597
+ * const result = await vana.data.uploadEncryptedFile(encrypted, filename);
36598
+ *
36599
+ * // New way:
36600
+ * const result = await vana.data.upload({
36601
+ * content: data,
36602
+ * filename: filename,
36603
+ * encrypt: true // Handles encryption automatically
36604
+ * });
36605
+ * ```
36145
36606
  * @param encryptedFile - The encrypted file blob to upload
36146
36607
  * @param filename - Optional filename for the upload
36147
36608
  * @param providerName - Optional storage provider to use
@@ -36229,7 +36690,22 @@ var DataController = class {
36229
36690
  /**
36230
36691
  * Uploads an encrypted file to storage and registers it on the blockchain with a schema.
36231
36692
  *
36232
- * @deprecated Use vana.data.upload() instead for the high-level API with automatic encryption and schema validation
36693
+ * @deprecated Since v2.0.0 - Use vana.data.upload() instead for the high-level API with automatic encryption and schema validation
36694
+ *
36695
+ * Migration guide:
36696
+ * ```typescript
36697
+ * // Old way (deprecated):
36698
+ * const encrypted = await encryptBlob(data, key);
36699
+ * const result = await vana.data.uploadEncryptedFileWithSchema(encrypted, schemaId, filename);
36700
+ *
36701
+ * // New way:
36702
+ * const result = await vana.data.upload({
36703
+ * content: data,
36704
+ * filename: filename,
36705
+ * schemaId: schemaId, // Automatic validation
36706
+ * encrypt: true
36707
+ * });
36708
+ * ```
36233
36709
  * @param encryptedFile - The encrypted file blob to upload
36234
36710
  * @param schemaId - The schema ID to associate with the file
36235
36711
  * @param filename - Optional filename for the upload
@@ -36372,6 +36848,7 @@ var DataController = class {
36372
36848
  * Gets the user's address from the wallet client.
36373
36849
  *
36374
36850
  * @returns Promise resolving to the user's wallet address
36851
+ * @throws {Error} When no addresses are available in wallet client
36375
36852
  */
36376
36853
  async getUserAddress() {
36377
36854
  const addresses = await this.context.walletClient.getAddresses();
@@ -36387,6 +36864,10 @@ var DataController = class {
36387
36864
  * @param ownerAddress - The address of the file owner
36388
36865
  * @param permissions - Array of permissions to set for the file
36389
36866
  * @returns Promise resolving to file ID and transaction hash
36867
+ * @throws {Error} When chain ID is not available
36868
+ * @throws {ContractError} When contract execution fails
36869
+ * @throws {Error} When transaction receipt is not available
36870
+ * @throws {Error} When FileAdded event cannot be parsed
36390
36871
  *
36391
36872
  * This method handles the core logic of registering a file
36392
36873
  * with specific permissions on the DataRegistry contract. It can be used
@@ -36451,6 +36932,10 @@ var DataController = class {
36451
36932
  * @param permissions - Array of permissions to grant (account and encrypted key)
36452
36933
  * @param schemaId - The schema ID to associate with the file (0 for no schema)
36453
36934
  * @returns Promise resolving to object with fileId and transactionHash
36935
+ * @throws {Error} When chain ID is not available
36936
+ * @throws {ContractError} When contract execution fails
36937
+ * @throws {Error} When transaction receipt is not available
36938
+ * @throws {Error} When FileAdded event cannot be parsed
36454
36939
  */
36455
36940
  async addFileWithPermissionsAndSchema(url, ownerAddress, permissions = [], schemaId = 0) {
36456
36941
  try {
@@ -36505,7 +36990,24 @@ var DataController = class {
36505
36990
  /**
36506
36991
  * Adds a new schema to the DataRefinerRegistry.
36507
36992
  *
36508
- * @deprecated Use vana.schemas.create() instead for the high-level API with automatic IPFS upload
36993
+ * @deprecated Since v2.0.0 - Use vana.schemas.create() instead for the high-level API with automatic IPFS upload
36994
+ *
36995
+ * Migration guide:
36996
+ * ```typescript
36997
+ * // Old way (deprecated):
36998
+ * const result = await vana.data.addSchema({
36999
+ * name: "UserProfile",
37000
+ * type: "JSON",
37001
+ * definitionUrl: "ipfs://..."
37002
+ * });
37003
+ *
37004
+ * // New way:
37005
+ * const result = await vana.schemas.create({
37006
+ * name: "UserProfile",
37007
+ * type: "JSON",
37008
+ * definition: schemaObject // Automatically uploads to IPFS
37009
+ * });
37010
+ * ```
36509
37011
  * @param params - Schema parameters including name, type, and definition URL
36510
37012
  * @returns Promise resolving to the new schema ID and transaction hash
36511
37013
  */
@@ -36564,7 +37066,16 @@ var DataController = class {
36564
37066
  /**
36565
37067
  * Retrieves a schema by its ID.
36566
37068
  *
36567
- * @deprecated Use vana.schemas.get() instead
37069
+ * @deprecated Since v2.0.0 - Use vana.schemas.get() instead
37070
+ *
37071
+ * Migration guide:
37072
+ * ```typescript
37073
+ * // Old way (deprecated):
37074
+ * const schema = await vana.data.getSchema(schemaId);
37075
+ *
37076
+ * // New way:
37077
+ * const schema = await vana.schemas.get(schemaId);
37078
+ * ```
36568
37079
  * @param schemaId - The schema ID to retrieve
36569
37080
  * @returns Promise resolving to the schema information
36570
37081
  */
@@ -36610,7 +37121,16 @@ var DataController = class {
36610
37121
  /**
36611
37122
  * Gets the total number of schemas in the registry.
36612
37123
  *
36613
- * @deprecated Use vana.schemas.count() instead
37124
+ * @deprecated Since v2.0.0 - Use vana.schemas.count() instead
37125
+ *
37126
+ * Migration guide:
37127
+ * ```typescript
37128
+ * // Old way (deprecated):
37129
+ * const count = await vana.data.getSchemasCount();
37130
+ *
37131
+ * // New way:
37132
+ * const count = await vana.schemas.count();
37133
+ * ```
36614
37134
  * @returns Promise resolving to the total schema count
36615
37135
  */
36616
37136
  async getSchemasCount() {
@@ -36859,6 +37379,7 @@ var DataController = class {
36859
37379
  try {
36860
37380
  const userEncryptionKey = await generateEncryptionKey(
36861
37381
  this.context.walletClient,
37382
+ this.context.platform,
36862
37383
  DEFAULT_ENCRYPTION_SEED
36863
37384
  );
36864
37385
  const encryptedData = await encryptBlobWithSignedKey(
@@ -36924,16 +37445,50 @@ var DataController = class {
36924
37445
  * 1. Gets the user's encryption key
36925
37446
  * 2. Encrypts the user's encryption key with the provided public key
36926
37447
  * 3. Adds the permission to the file
37448
+ * 4. Returns the permission data from the blockchain event
37449
+ *
37450
+ * For advanced users who need more control over transaction timing,
37451
+ * use `submitFilePermission()` instead.
37452
+ *
37453
+ * @param fileId - The ID of the file to add permissions for
37454
+ * @param account - The address of the account to grant permission to
37455
+ * @param publicKey - The public key to encrypt the user's encryption key with (hex string with 0x prefix)
37456
+ * @returns Promise resolving to permission data from PermissionGranted event
37457
+ * @throws {Error} "No addresses available in wallet client" - When wallet is not connected
37458
+ * @throws {Error} "Chain ID not available" - When wallet chain is not configured
37459
+ * @throws {Error} "Failed to add permission to file: {error}" - When transaction fails or user doesn't own file
37460
+ * @example
37461
+ * ```typescript
37462
+ * const result = await vana.data.addPermissionToFile(fileId, account, publicKey);
37463
+ * console.log(`Permission granted to ${result.account} for file ${result.fileId}`);
37464
+ * console.log(`Transaction: ${result.transactionHash}`);
37465
+ * ```
37466
+ */
37467
+ async addPermissionToFile(fileId, account, publicKey) {
37468
+ const txHash = await this.submitFilePermission(fileId, account, publicKey);
37469
+ return parseTransactionResult(this.context, txHash, "addFilePermission");
37470
+ }
37471
+ /**
37472
+ * Submits a file permission transaction and returns the transaction hash immediately.
37473
+ *
37474
+ * This is the lower-level method that provides maximum control over transaction timing.
37475
+ * Use this when you want to handle transaction confirmation and event parsing separately.
36927
37476
  *
36928
37477
  * @param fileId - The ID of the file to add permissions for
36929
37478
  * @param account - The address of the account to grant permission to
36930
37479
  * @param publicKey - The public key to encrypt the user's encryption key with
36931
37480
  * @returns Promise resolving to the transaction hash
37481
+ * @example
37482
+ * ```typescript
37483
+ * const txHash = await vana.data.submitFilePermission(fileId, account, publicKey);
37484
+ * console.log(`Transaction submitted: ${txHash}`);
37485
+ * ```
36932
37486
  */
36933
- async addPermissionToFile(fileId, account, publicKey) {
37487
+ async submitFilePermission(fileId, account, publicKey) {
36934
37488
  try {
36935
37489
  const userEncryptionKey = await generateEncryptionKey(
36936
37490
  this.context.walletClient,
37491
+ this.context.platform,
36937
37492
  DEFAULT_ENCRYPTION_SEED
36938
37493
  );
36939
37494
  const encryptedKey = await encryptWithWalletPublicKey(
@@ -37054,7 +37609,9 @@ var DataController = class {
37054
37609
  *
37055
37610
  * @param url - The URL to fetch content from
37056
37611
  * @returns Promise resolving to the fetched content as a Blob
37057
- * @throws {Error} When the fetch fails or returns a non-ok response
37612
+ * @throws {Error} "HTTP error! status: {status} {statusText}" - When server returns error status
37613
+ * @throws {Error} "Empty response" - When server returns no content
37614
+ * @throws {Error} "Network error: Failed to fetch from {url}" - When network request fails
37058
37615
  *
37059
37616
  * @example
37060
37617
  * ```typescript
@@ -37106,7 +37663,10 @@ var DataController = class {
37106
37663
  * @param options - Optional configuration
37107
37664
  * @param options.gateways - Array of IPFS gateway URLs to try (must end with /)
37108
37665
  * @returns Promise resolving to the fetched content as a Blob
37109
- * @throws {Error} When all gateways fail to fetch the content
37666
+ * @throws {Error} "Invalid IPFS URL format" - When URL is not ipfs:// or valid CID
37667
+ * @throws {Error} "Empty response" - When gateway returns no content
37668
+ * @throws {Error} "HTTP error! status: {status}" - When gateway returns error status
37669
+ * @throws {Error} "Failed to fetch IPFS content {cid} from all gateways" - When all gateways fail
37110
37670
  *
37111
37671
  * @example
37112
37672
  * ```typescript
@@ -37647,6 +38207,39 @@ var ServerController = class {
37647
38207
  this.context = context;
37648
38208
  __publicField(this, "PERSONAL_SERVER_BASE_URL", process.env.NEXT_PUBLIC_PERSONAL_SERVER_BASE_URL);
37649
38209
  }
38210
+ /**
38211
+ * Retrieves the cryptographic identity of a personal server.
38212
+ *
38213
+ * @remarks
38214
+ * This method fetches the public key and metadata for a personal server,
38215
+ * which is required for encrypting data before sharing with the server.
38216
+ * The identity includes the server's public key, address, and operational
38217
+ * details needed for secure communication. This information is cached
38218
+ * by identity servers to enable offline key retrieval.
38219
+ *
38220
+ * @param request - Parameters containing the user address
38221
+ * @param request.userAddress - The wallet address associated with the personal server
38222
+ * @returns Promise resolving to the server's identity information
38223
+ * @throws {NetworkError} When the identity service is unavailable or returns invalid data
38224
+ * @throws {PersonalServerError} When server identity cannot be retrieved
38225
+ * @example
38226
+ * ```typescript
38227
+ * // Get server identity for data encryption
38228
+ * const identity = await vana.server.getIdentity({
38229
+ * userAddress: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36"
38230
+ * });
38231
+ *
38232
+ * console.log(`Server: ${identity.name}`);
38233
+ * console.log(`Address: ${identity.address}`);
38234
+ * console.log(`Public Key: ${identity.public_key}`);
38235
+ *
38236
+ * // Use the public key for encrypting data to share with this server
38237
+ * const encryptedData = await encryptWithWalletPublicKey(
38238
+ * userData,
38239
+ * identity.public_key
38240
+ * );
38241
+ * ```
38242
+ */
37650
38243
  async getIdentity(request) {
37651
38244
  try {
37652
38245
  const response = await fetch(
@@ -37689,10 +38282,13 @@ var ServerController = class {
37689
38282
  * This method submits a computation request to the personal server API.
37690
38283
  * The response includes the operation ID.
37691
38284
  * @param params - The request parameters object
37692
- * @param params.permissionId - The permission ID authorizing this operation
38285
+ * @param params.permissionId - The permission ID authorizing this operation.
38286
+ * Obtain from granted permissions via `vana.permissions.getUserPermissionGrantsOnChain()`.
37693
38287
  * @returns A Promise that resolves to an operation response with status and control URLs
37694
- * @throws {PersonalServerError} When server request fails or parameters are invalid
37695
- * @throws {NetworkError} When personal server API communication fails
38288
+ * @throws {PersonalServerError} When server request fails or parameters are invalid.
38289
+ * Verify permissionId exists and is active for the target server.
38290
+ * @throws {NetworkError} When personal server API communication fails.
38291
+ * Check server URL configuration and network connectivity.
37696
38292
  * @example
37697
38293
  * ```typescript
37698
38294
  * const response = await vana.server.createOperation({
@@ -37794,6 +38390,50 @@ var ServerController = class {
37794
38390
  );
37795
38391
  }
37796
38392
  }
38393
+ /**
38394
+ * Cancels a running operation on the personal server.
38395
+ *
38396
+ * @remarks
38397
+ * This method attempts to cancel an operation that is currently processing
38398
+ * on the personal server. The operation must be in a cancellable state
38399
+ * (typically `starting` or `processing`). Not all operations support
38400
+ * cancellation, and cancellation may not be immediate. The server will
38401
+ * attempt to stop the operation and update its status to `canceled`.
38402
+ *
38403
+ * **Cancellation Behavior:**
38404
+ * - Operations in `succeeded` or `failed` states cannot be canceled
38405
+ * - Some long-running operations may take time to respond to cancellation
38406
+ * - Always verify cancellation by polling the operation status afterward
38407
+ *
38408
+ * @param operationId - The unique identifier of the operation to cancel,
38409
+ * obtained from `createOperation()` response
38410
+ * @returns Promise that resolves when the cancellation request is accepted
38411
+ * @throws {PersonalServerError} When the operation cannot be canceled or doesn't exist.
38412
+ * Check operation status - it may already be completed or failed.
38413
+ * @throws {NetworkError} When unable to reach the personal server API.
38414
+ * Verify server URL and network connectivity.
38415
+ * @example
38416
+ * ```typescript
38417
+ * // Start a long-running operation
38418
+ * const operation = await vana.server.createOperation({
38419
+ * permissionId: 123
38420
+ * });
38421
+ *
38422
+ * // Cancel if needed
38423
+ * try {
38424
+ * await vana.server.cancelOperation(operation.id);
38425
+ * console.log("Cancellation requested");
38426
+ *
38427
+ * // Verify cancellation
38428
+ * const status = await vana.server.getOperation(operation.id);
38429
+ * if (status.status === "canceled") {
38430
+ * console.log("Operation successfully canceled");
38431
+ * }
38432
+ * } catch (error) {
38433
+ * console.error("Failed to cancel:", error);
38434
+ * }
38435
+ * ```
38436
+ */
37797
38437
  async cancelOperation(operationId) {
37798
38438
  try {
37799
38439
  const response = await fetch(
@@ -38097,7 +38737,8 @@ var ProtocolController = class {
38097
38737
  * are actually deployed on the current network.
38098
38738
  * @param contractName - The name of the Vana contract to retrieve (use const assertion for full typing)
38099
38739
  * @returns An object containing the contract's address and fully typed ABI
38100
- * @throws {ContractNotFoundError} When the contract is not deployed on the current chain
38740
+ * @throws {ContractNotFoundError} When the contract is not deployed on the current chain.
38741
+ * Verify contract name spelling and check current network with `getChainId()`.
38101
38742
  * @example
38102
38743
  * ```typescript
38103
38744
  * // Get contract info with full type inference
@@ -38206,6 +38847,7 @@ var ProtocolController = class {
38206
38847
  * Gets the current chain ID from the wallet client.
38207
38848
  *
38208
38849
  * @returns The chain ID
38850
+ * @throws {Error} When chain ID is not available from wallet client
38209
38851
  */
38210
38852
  getChainId() {
38211
38853
  const chainId = this.context.walletClient.chain?.id;
@@ -38218,6 +38860,7 @@ var ProtocolController = class {
38218
38860
  * Gets the current chain name from the wallet client.
38219
38861
  *
38220
38862
  * @returns The chain name
38863
+ * @throws {Error} When chain name is not available from wallet client
38221
38864
  */
38222
38865
  getChainName() {
38223
38866
  const chainName = this.context.walletClient.chain?.name;
@@ -38718,6 +39361,7 @@ var GoogleDriveStorage = class {
38718
39361
  };
38719
39362
 
38720
39363
  // src/storage/providers/ipfs.ts
39364
+ init_crypto_utils();
38721
39365
  var IpfsStorage = class _IpfsStorage {
38722
39366
  constructor(config) {
38723
39367
  this.config = config;
@@ -38757,7 +39401,7 @@ var IpfsStorage = class _IpfsStorage {
38757
39401
  * ```
38758
39402
  */
38759
39403
  static forInfura(credentials) {
38760
- const auth = btoa(`${credentials.projectId}:${credentials.projectSecret}`);
39404
+ const auth = toBase64(`${credentials.projectId}:${credentials.projectSecret}`);
38761
39405
  return new _IpfsStorage({
38762
39406
  apiEndpoint: "https://ipfs.infura.io:5001/api/v0/add",
38763
39407
  gatewayUrl: "https://ipfs.infura.io/ipfs",
@@ -40049,15 +40693,35 @@ var VanaCore = class {
40049
40693
  }
40050
40694
  /**
40051
40695
  * Encrypts data using the Vana protocol standard encryption.
40052
- * This method automatically uses the correct platform adapter for the current environment.
40696
+ *
40697
+ * @remarks
40698
+ * This method implements the Vana network's standard encryption protocol using
40699
+ * platform-appropriate cryptographic libraries. It automatically handles different
40700
+ * input types (string or Blob) and produces encrypted output suitable for secure
40701
+ * storage or transmission. The encryption is compatible with the network's
40702
+ * decryption protocols and can be decrypted by authorized parties.
40053
40703
  *
40054
- * @param data The data to encrypt (string or Blob)
40055
- * @param key The key to use as encryption key
40056
- * @returns The encrypted data as Blob
40704
+ * @param data - The data to encrypt (string or Blob)
40705
+ * @param key - The encryption key (typically generated via `generateEncryptionKey`)
40706
+ * @returns The encrypted data as a Blob
40707
+ * @throws {Error} When encryption fails due to invalid key or data format
40057
40708
  * @example
40058
40709
  * ```typescript
40059
- * const encryptionKey = await generateEncryptionKey(walletClient);
40060
- * const encrypted = await vana.encryptBlob("sensitive data", encryptionKey);
40710
+ * import { generateEncryptionKey } from '@opendatalabs/vana-sdk/node';
40711
+ *
40712
+ * // Generate encryption key from wallet signature
40713
+ * const encryptionKey = await generateEncryptionKey(vana.walletClient);
40714
+ *
40715
+ * // Encrypt string data
40716
+ * const sensitiveData = "User's private information";
40717
+ * const encrypted = await vana.encryptBlob(sensitiveData, encryptionKey);
40718
+ *
40719
+ * // Encrypt file data
40720
+ * const fileBlob = new Blob([fileContent], { type: 'application/json' });
40721
+ * const encryptedFile = await vana.encryptBlob(fileBlob, encryptionKey);
40722
+ *
40723
+ * // Store encrypted data safely
40724
+ * await storageProvider.upload(encrypted, 'encrypted-data.bin');
40061
40725
  * ```
40062
40726
  */
40063
40727
  async encryptBlob(data, key) {
@@ -40065,16 +40729,52 @@ var VanaCore = class {
40065
40729
  }
40066
40730
  /**
40067
40731
  * Decrypts data that was encrypted using the Vana protocol.
40068
- * This method automatically uses the correct platform adapter for the current environment.
40732
+ *
40733
+ * @remarks
40734
+ * This method decrypts data that was previously encrypted using the Vana network's
40735
+ * standard encryption protocol. It requires the same wallet signature that was used
40736
+ * for encryption and automatically uses the appropriate platform adapter for
40737
+ * cryptographic operations. The decrypted output maintains the original data format.
40069
40738
  *
40070
- * @param encryptedData The encrypted data (string or Blob)
40071
- * @param walletSignature The wallet signature to use as decryption key
40072
- * @returns The decrypted data as Blob
40739
+ * @param encryptedData - The encrypted data (string or Blob)
40740
+ * @param walletSignature - The wallet signature used as decryption key
40741
+ * @returns The decrypted data as a Blob
40742
+ * @throws {Error} When decryption fails due to invalid signature or corrupted data
40073
40743
  * @example
40074
40744
  * ```typescript
40075
- * const encryptionKey = await generateEncryptionKey(walletClient);
40076
- * const decrypted = await vana.decryptBlob(encryptedData, encryptionKey);
40077
- * const text = await decrypted.text();
40745
+ * import { generateEncryptionKey } from '@opendatalabs/vana-sdk/node';
40746
+ *
40747
+ * // Retrieve encrypted data from storage
40748
+ * const encryptedBlob = await storageProvider.download('encrypted-data.bin');
40749
+ *
40750
+ * // Generate the same key used for encryption
40751
+ * const decryptionKey = await generateEncryptionKey(vana.walletClient);
40752
+ *
40753
+ * // Decrypt the data
40754
+ * const decrypted = await vana.decryptBlob(encryptedBlob, decryptionKey);
40755
+ *
40756
+ * // Convert back to original format
40757
+ * const originalText = await decrypted.text();
40758
+ * const originalJson = JSON.parse(originalText);
40759
+ *
40760
+ * console.log('Decrypted data:', originalJson);
40761
+ * ```
40762
+ *
40763
+ * @example
40764
+ * ```typescript
40765
+ * // Decrypt file downloaded from Vana network
40766
+ * const userFiles = await vana.data.getUserFiles();
40767
+ * const file = userFiles[0];
40768
+ *
40769
+ * // Download encrypted content
40770
+ * const encrypted = await fetch(file.url).then(r => r.blob());
40771
+ *
40772
+ * // Decrypt with user's key
40773
+ * const decryptionKey = await generateEncryptionKey(vana.walletClient);
40774
+ * const decrypted = await vana.decryptBlob(encrypted, decryptionKey);
40775
+ *
40776
+ * // Process original data
40777
+ * const fileContent = await decrypted.arrayBuffer();
40078
40778
  * ```
40079
40779
  */
40080
40780
  async decryptBlob(encryptedData, walletSignature) {
@@ -40919,6 +41619,7 @@ export {
40919
41619
  SerializationError,
40920
41620
  ServerController,
40921
41621
  ServerUrlMismatchError,
41622
+ SignatureCache,
40922
41623
  SignatureError,
40923
41624
  StorageError,
40924
41625
  StorageManager,
@@ -40989,6 +41690,7 @@ export {
40989
41690
  validateGrantFile,
40990
41691
  validateGranteeAccess,
40991
41692
  validateOperationAccess,
40992
- vanaMainnet2 as vanaMainnet
41693
+ vanaMainnet2 as vanaMainnet,
41694
+ withSignatureCache
40993
41695
  };
40994
41696
  //# sourceMappingURL=index.browser.js.map