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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (907) hide show
  1. package/README.md +13 -4
  2. package/dist/__tests__/waitForTransactionEvents.test.d.ts +1 -0
  3. package/dist/browser.cjs +29 -0
  4. package/dist/browser.cjs.map +1 -0
  5. package/dist/browser.d.ts +36 -1
  6. package/dist/browser.js +1 -305
  7. package/dist/browser.js.map +1 -1
  8. package/dist/{chains.browser.cjs → chains/definitions.cjs} +16 -17
  9. package/dist/chains/definitions.cjs.map +1 -0
  10. package/dist/{chains.browser.d.cts → chains/definitions.d.ts} +9 -11
  11. package/dist/chains/definitions.js +67 -0
  12. package/dist/chains/definitions.js.map +1 -0
  13. package/dist/chains/index.cjs +37 -0
  14. package/dist/chains/index.cjs.map +1 -0
  15. package/dist/chains/index.d.ts +34 -0
  16. package/dist/chains/index.js +15 -0
  17. package/dist/chains/index.js.map +1 -0
  18. package/dist/chains.browser.d.ts +5 -50
  19. package/dist/chains.browser.js +7 -57
  20. package/dist/chains.browser.js.map +1 -1
  21. package/dist/chains.cjs +6 -65
  22. package/dist/chains.cjs.map +1 -1
  23. package/dist/chains.d.ts +8 -2
  24. package/dist/chains.js +7 -57
  25. package/dist/chains.js.map +1 -1
  26. package/dist/chains.node.cjs +6 -65
  27. package/dist/chains.node.cjs.map +1 -1
  28. package/dist/chains.node.d.ts +8 -2
  29. package/dist/chains.node.js +7 -57
  30. package/dist/chains.node.js.map +1 -1
  31. package/dist/client/__tests__/enhancedResponse.test.d.ts +1 -0
  32. package/dist/client/enhancedResponse.cjs +164 -0
  33. package/dist/client/enhancedResponse.cjs.map +1 -0
  34. package/dist/client/enhancedResponse.d.ts +120 -0
  35. package/dist/client/enhancedResponse.js +138 -0
  36. package/dist/client/enhancedResponse.js.map +1 -0
  37. package/dist/config/addresses.cjs +325 -0
  38. package/dist/config/addresses.cjs.map +1 -0
  39. package/dist/config/addresses.d.ts +364 -0
  40. package/dist/config/addresses.js +295 -0
  41. package/dist/config/addresses.js.map +1 -0
  42. package/dist/config/chains.cjs +93 -0
  43. package/dist/config/chains.cjs.map +1 -0
  44. package/dist/config/chains.d.ts +180 -0
  45. package/dist/config/chains.js +67 -0
  46. package/dist/config/chains.js.map +1 -0
  47. package/dist/config/default-services.cjs +60 -0
  48. package/dist/config/default-services.cjs.map +1 -0
  49. package/dist/config/default-services.d.ts +46 -0
  50. package/dist/config/default-services.js +33 -0
  51. package/dist/config/default-services.js.map +1 -0
  52. package/dist/config/default-services.test.d.ts +1 -0
  53. package/dist/config/features.cjs +52 -0
  54. package/dist/config/features.cjs.map +1 -0
  55. package/dist/config/features.d.ts +62 -0
  56. package/dist/config/features.js +28 -0
  57. package/dist/config/features.js.map +1 -0
  58. package/dist/config/tests/addresses.test.d.ts +1 -0
  59. package/dist/contracts/contractController.cjs +126 -0
  60. package/dist/contracts/contractController.cjs.map +1 -0
  61. package/dist/contracts/contractController.d.ts +135 -0
  62. package/dist/contracts/contractController.js +100 -0
  63. package/dist/contracts/contractController.js.map +1 -0
  64. package/dist/contracts/tests/contractController.test.d.ts +1 -0
  65. package/dist/controllers/__tests__/data-consistency-integration.test.d.ts +7 -0
  66. package/dist/controllers/__tests__/operations.processQueue.test.d.ts +1 -0
  67. package/dist/controllers/__tests__/schemas-edge-cases.test.d.ts +1 -0
  68. package/dist/controllers/base.cjs +116 -0
  69. package/dist/controllers/base.cjs.map +1 -0
  70. package/dist/controllers/base.d.ts +94 -0
  71. package/dist/controllers/base.js +92 -0
  72. package/dist/controllers/base.js.map +1 -0
  73. package/dist/controllers/data-error-handling.test.d.ts +1 -0
  74. package/dist/controllers/data.cjs +2633 -0
  75. package/dist/controllers/data.cjs.map +1 -0
  76. package/dist/controllers/data.d.ts +1067 -0
  77. package/dist/controllers/data.js +2626 -0
  78. package/dist/controllers/data.js.map +1 -0
  79. package/dist/controllers/operations.cjs +430 -0
  80. package/dist/controllers/operations.cjs.map +1 -0
  81. package/dist/controllers/operations.d.ts +229 -0
  82. package/dist/controllers/operations.js +406 -0
  83. package/dist/controllers/operations.js.map +1 -0
  84. package/dist/controllers/permissions.cjs +4363 -0
  85. package/dist/controllers/permissions.cjs.map +1 -0
  86. package/dist/controllers/permissions.d.ts +1411 -0
  87. package/dist/controllers/permissions.js +4339 -0
  88. package/dist/controllers/permissions.js.map +1 -0
  89. package/dist/controllers/protocol.cjs +183 -0
  90. package/dist/controllers/protocol.cjs.map +1 -0
  91. package/dist/controllers/protocol.d.ts +138 -0
  92. package/dist/controllers/protocol.js +163 -0
  93. package/dist/controllers/protocol.js.map +1 -0
  94. package/dist/controllers/schemas.cjs +678 -0
  95. package/dist/controllers/schemas.cjs.map +1 -0
  96. package/dist/controllers/schemas.d.ts +293 -0
  97. package/dist/controllers/schemas.js +654 -0
  98. package/dist/controllers/schemas.js.map +1 -0
  99. package/dist/controllers/server-additional.test.d.ts +1 -0
  100. package/dist/controllers/server.cjs +643 -0
  101. package/dist/controllers/server.cjs.map +1 -0
  102. package/dist/controllers/server.d.ts +322 -0
  103. package/dist/controllers/server.js +624 -0
  104. package/dist/controllers/server.js.map +1 -0
  105. package/dist/core/__tests__/health.test.d.ts +1 -0
  106. package/dist/core/__tests__/inMemoryNonceManager.test.d.ts +1 -0
  107. package/dist/core/__tests__/nonceManager.test.d.ts +1 -0
  108. package/dist/core/__tests__/pollingManager.test.d.ts +4 -0
  109. package/dist/core/apiClient.cjs +378 -0
  110. package/dist/core/apiClient.cjs.map +1 -0
  111. package/dist/core/apiClient.d.ts +286 -0
  112. package/dist/core/apiClient.js +359 -0
  113. package/dist/core/apiClient.js.map +1 -0
  114. package/dist/core/client.cjs +70 -0
  115. package/dist/core/client.cjs.map +1 -0
  116. package/dist/core/client.d.ts +89 -0
  117. package/dist/core/client.js +47 -0
  118. package/dist/core/client.js.map +1 -0
  119. package/dist/core/core.test.d.ts +1 -0
  120. package/dist/core/generics.cjs +417 -0
  121. package/dist/core/generics.cjs.map +1 -0
  122. package/dist/core/generics.d.ts +205 -0
  123. package/dist/core/generics.js +386 -0
  124. package/dist/core/generics.js.map +1 -0
  125. package/dist/core/health.cjs +289 -0
  126. package/dist/core/health.cjs.map +1 -0
  127. package/dist/core/health.d.ts +143 -0
  128. package/dist/core/health.js +265 -0
  129. package/dist/core/health.js.map +1 -0
  130. package/dist/core/inMemoryNonceManager.cjs +138 -0
  131. package/dist/core/inMemoryNonceManager.cjs.map +1 -0
  132. package/dist/core/inMemoryNonceManager.d.ts +69 -0
  133. package/dist/core/inMemoryNonceManager.js +114 -0
  134. package/dist/core/inMemoryNonceManager.js.map +1 -0
  135. package/dist/core/nonceManager.cjs +304 -0
  136. package/dist/core/nonceManager.cjs.map +1 -0
  137. package/dist/core/nonceManager.d.ts +116 -0
  138. package/dist/core/nonceManager.js +280 -0
  139. package/dist/core/nonceManager.js.map +1 -0
  140. package/dist/core/pollingManager.cjs +292 -0
  141. package/dist/core/pollingManager.cjs.map +1 -0
  142. package/dist/core/pollingManager.d.ts +120 -0
  143. package/dist/core/pollingManager.js +268 -0
  144. package/dist/core/pollingManager.js.map +1 -0
  145. package/dist/core/tests/apiClient.test.d.ts +1 -0
  146. package/dist/core/tests/client.test.d.ts +1 -0
  147. package/dist/core/tests/generics.test.d.ts +1 -0
  148. package/dist/core.cjs +777 -0
  149. package/dist/core.cjs.map +1 -0
  150. package/dist/core.d.ts +493 -0
  151. package/dist/core.js +752 -0
  152. package/dist/core.js.map +1 -0
  153. package/dist/crypto/ecies/__tests__/base.test.d.ts +4 -0
  154. package/dist/crypto/ecies/__tests__/compatibility.test.d.ts +8 -0
  155. package/dist/crypto/ecies/__tests__/constants.test.d.ts +4 -0
  156. package/dist/crypto/ecies/__tests__/native-parity.test.d.ts +7 -0
  157. package/dist/crypto/ecies/__tests__/normalization.test.d.ts +1 -0
  158. package/dist/crypto/ecies/__tests__/test-vectors.cjs +102 -0
  159. package/dist/crypto/ecies/__tests__/test-vectors.cjs.map +1 -0
  160. package/dist/crypto/ecies/__tests__/test-vectors.d.ts +38 -0
  161. package/dist/crypto/ecies/__tests__/test-vectors.js +77 -0
  162. package/dist/crypto/ecies/__tests__/test-vectors.js.map +1 -0
  163. package/dist/crypto/ecies/base.cjs +245 -0
  164. package/dist/crypto/ecies/base.cjs.map +1 -0
  165. package/dist/crypto/ecies/base.d.ts +140 -0
  166. package/dist/crypto/ecies/base.js +221 -0
  167. package/dist/crypto/ecies/base.js.map +1 -0
  168. package/dist/crypto/ecies/browser.cjs +165 -0
  169. package/dist/crypto/ecies/browser.cjs.map +1 -0
  170. package/dist/crypto/ecies/browser.d.ts +43 -0
  171. package/dist/crypto/ecies/browser.js +131 -0
  172. package/dist/crypto/ecies/browser.js.map +1 -0
  173. package/dist/crypto/ecies/constants.cjs +131 -0
  174. package/dist/crypto/ecies/constants.cjs.map +1 -0
  175. package/dist/crypto/ecies/constants.d.ts +120 -0
  176. package/dist/crypto/ecies/constants.js +101 -0
  177. package/dist/crypto/ecies/constants.js.map +1 -0
  178. package/dist/crypto/ecies/index.cjs +35 -0
  179. package/dist/crypto/ecies/index.cjs.map +1 -0
  180. package/dist/crypto/ecies/index.d.ts +8 -0
  181. package/dist/crypto/ecies/index.js +13 -0
  182. package/dist/crypto/ecies/index.js.map +1 -0
  183. package/dist/crypto/ecies/interface.cjs +87 -0
  184. package/dist/crypto/ecies/interface.cjs.map +1 -0
  185. package/dist/crypto/ecies/interface.d.ts +174 -0
  186. package/dist/crypto/ecies/interface.js +60 -0
  187. package/dist/crypto/ecies/interface.js.map +1 -0
  188. package/dist/crypto/ecies/node.cjs +167 -0
  189. package/dist/crypto/ecies/node.cjs.map +1 -0
  190. package/dist/crypto/ecies/node.d.ts +45 -0
  191. package/dist/crypto/ecies/node.js +139 -0
  192. package/dist/crypto/ecies/node.js.map +1 -0
  193. package/dist/crypto/ecies/test-vectors/eccrypto-vectors.json +72 -0
  194. package/dist/crypto/ecies/utils.cjs +52 -0
  195. package/dist/crypto/ecies/utils.cjs.map +1 -0
  196. package/dist/crypto/ecies/utils.d.ts +30 -0
  197. package/dist/crypto/ecies/utils.js +26 -0
  198. package/dist/crypto/ecies/utils.js.map +1 -0
  199. package/dist/crypto/services/WalletKeyEncryptionService.cjs +128 -0
  200. package/dist/crypto/services/WalletKeyEncryptionService.cjs.map +1 -0
  201. package/dist/crypto/services/WalletKeyEncryptionService.d.ts +88 -0
  202. package/dist/crypto/services/WalletKeyEncryptionService.js +108 -0
  203. package/dist/crypto/services/WalletKeyEncryptionService.js.map +1 -0
  204. package/dist/crypto/services/WalletKeyEncryptionService.test.d.ts +1 -0
  205. package/dist/diagnostics.cjs +37 -0
  206. package/dist/diagnostics.cjs.map +1 -0
  207. package/dist/diagnostics.d.ts +24 -0
  208. package/dist/diagnostics.js +13 -0
  209. package/dist/diagnostics.js.map +1 -0
  210. package/dist/diagnostics.test.d.ts +1 -0
  211. package/dist/errors.cjs +186 -0
  212. package/dist/errors.cjs.map +1 -0
  213. package/dist/errors.d.ts +452 -0
  214. package/dist/errors.js +148 -0
  215. package/dist/errors.js.map +1 -0
  216. package/dist/generated/abi/ComputeEngineImplementation.cjs +1313 -0
  217. package/dist/generated/abi/ComputeEngineImplementation.cjs.map +1 -0
  218. package/dist/generated/abi/ComputeEngineImplementation.d.ts +995 -0
  219. package/dist/generated/abi/ComputeEngineImplementation.js +1289 -0
  220. package/dist/generated/abi/ComputeEngineImplementation.js.map +1 -0
  221. package/dist/generated/abi/ComputeInstructionRegistryImplementation.cjs +734 -0
  222. package/dist/generated/abi/ComputeInstructionRegistryImplementation.cjs.map +1 -0
  223. package/dist/generated/abi/ComputeInstructionRegistryImplementation.d.ts +544 -0
  224. package/dist/generated/abi/ComputeInstructionRegistryImplementation.js +710 -0
  225. package/dist/generated/abi/ComputeInstructionRegistryImplementation.js.map +1 -0
  226. package/dist/generated/abi/DATFactoryImplementation.cjs +882 -0
  227. package/dist/generated/abi/DATFactoryImplementation.cjs.map +1 -0
  228. package/dist/generated/abi/DATFactoryImplementation.d.ts +660 -0
  229. package/dist/generated/abi/DATFactoryImplementation.js +858 -0
  230. package/dist/generated/abi/DATFactoryImplementation.js.map +1 -0
  231. package/dist/generated/abi/DATImplementation.cjs +934 -0
  232. package/dist/generated/abi/DATImplementation.cjs.map +1 -0
  233. package/dist/generated/abi/DATImplementation.d.ts +692 -0
  234. package/dist/generated/abi/DATImplementation.js +910 -0
  235. package/dist/generated/abi/DATImplementation.js.map +1 -0
  236. package/dist/generated/abi/DATPausableImplementation.cjs +1523 -0
  237. package/dist/generated/abi/DATPausableImplementation.cjs.map +1 -0
  238. package/dist/generated/abi/DATPausableImplementation.d.ts +1144 -0
  239. package/dist/generated/abi/DATPausableImplementation.js +1499 -0
  240. package/dist/generated/abi/DATPausableImplementation.js.map +1 -0
  241. package/dist/generated/abi/DATVotesImplementation.cjs +1460 -0
  242. package/dist/generated/abi/DATVotesImplementation.cjs.map +1 -0
  243. package/dist/generated/abi/DATVotesImplementation.d.ts +1094 -0
  244. package/dist/generated/abi/DATVotesImplementation.js +1436 -0
  245. package/dist/generated/abi/DATVotesImplementation.js.map +1 -0
  246. package/dist/generated/abi/DLPPerformanceImplementation.cjs +1202 -0
  247. package/dist/generated/abi/DLPPerformanceImplementation.cjs.map +1 -0
  248. package/dist/generated/abi/DLPPerformanceImplementation.d.ts +914 -0
  249. package/dist/generated/abi/DLPPerformanceImplementation.js +1178 -0
  250. package/dist/generated/abi/DLPPerformanceImplementation.js.map +1 -0
  251. package/dist/generated/abi/DLPRegistryImplementation.cjs +1469 -0
  252. package/dist/generated/abi/DLPRegistryImplementation.cjs.map +1 -0
  253. package/dist/generated/abi/DLPRegistryImplementation.d.ts +1122 -0
  254. package/dist/generated/abi/DLPRegistryImplementation.js +1445 -0
  255. package/dist/generated/abi/DLPRegistryImplementation.js.map +1 -0
  256. package/dist/generated/abi/DLPRegistryTreasuryImplementation.cjs +612 -0
  257. package/dist/generated/abi/DLPRegistryTreasuryImplementation.cjs.map +1 -0
  258. package/dist/generated/abi/DLPRegistryTreasuryImplementation.d.ts +451 -0
  259. package/dist/generated/abi/DLPRegistryTreasuryImplementation.js +588 -0
  260. package/dist/generated/abi/DLPRegistryTreasuryImplementation.js.map +1 -0
  261. package/dist/generated/abi/DLPRewardDeployerImplementation.cjs +1112 -0
  262. package/dist/generated/abi/DLPRewardDeployerImplementation.cjs.map +1 -0
  263. package/dist/generated/abi/DLPRewardDeployerImplementation.d.ts +840 -0
  264. package/dist/generated/abi/DLPRewardDeployerImplementation.js +1088 -0
  265. package/dist/generated/abi/DLPRewardDeployerImplementation.js.map +1 -0
  266. package/dist/generated/abi/DLPRewardDeployerTreasuryImplementation.cjs +612 -0
  267. package/dist/generated/abi/DLPRewardDeployerTreasuryImplementation.cjs.map +1 -0
  268. package/dist/generated/abi/DLPRewardDeployerTreasuryImplementation.d.ts +451 -0
  269. package/dist/generated/abi/DLPRewardDeployerTreasuryImplementation.js +588 -0
  270. package/dist/generated/abi/DLPRewardDeployerTreasuryImplementation.js.map +1 -0
  271. package/dist/generated/abi/DLPRewardSwapImplementation.cjs +939 -0
  272. package/dist/generated/abi/DLPRewardSwapImplementation.cjs.map +1 -0
  273. package/dist/generated/abi/DLPRewardSwapImplementation.d.ts +705 -0
  274. package/dist/generated/abi/DLPRewardSwapImplementation.js +915 -0
  275. package/dist/generated/abi/DLPRewardSwapImplementation.js.map +1 -0
  276. package/dist/generated/abi/DLPRootImplementation.cjs +1644 -0
  277. package/dist/generated/abi/DLPRootImplementation.cjs.map +1 -0
  278. package/dist/generated/abi/DLPRootImplementation.d.ts +1246 -0
  279. package/dist/generated/abi/DLPRootImplementation.js +1620 -0
  280. package/dist/generated/abi/DLPRootImplementation.js.map +1 -0
  281. package/dist/generated/abi/DLPTreasuryImplementation.cjs +612 -0
  282. package/dist/generated/abi/DLPTreasuryImplementation.cjs.map +1 -0
  283. package/dist/generated/abi/DLPTreasuryImplementation.d.ts +451 -0
  284. package/dist/generated/abi/DLPTreasuryImplementation.js +588 -0
  285. package/dist/generated/abi/DLPTreasuryImplementation.js.map +1 -0
  286. package/dist/generated/abi/DataLiquidityPoolImplementation.cjs +985 -0
  287. package/dist/generated/abi/DataLiquidityPoolImplementation.cjs.map +1 -0
  288. package/dist/generated/abi/DataLiquidityPoolImplementation.d.ts +735 -0
  289. package/dist/generated/abi/DataLiquidityPoolImplementation.js +961 -0
  290. package/dist/generated/abi/DataLiquidityPoolImplementation.js.map +1 -0
  291. package/dist/generated/abi/DataPortabilityGranteesImplementation.cjs +1036 -0
  292. package/dist/generated/abi/DataPortabilityGranteesImplementation.cjs.map +1 -0
  293. package/dist/generated/abi/DataPortabilityGranteesImplementation.d.ts +773 -0
  294. package/dist/generated/abi/DataPortabilityGranteesImplementation.js +1012 -0
  295. package/dist/generated/abi/DataPortabilityGranteesImplementation.js.map +1 -0
  296. package/dist/generated/abi/DataPortabilityPermissionsImplementation.cjs +1298 -0
  297. package/dist/generated/abi/DataPortabilityPermissionsImplementation.cjs.map +1 -0
  298. package/dist/generated/abi/DataPortabilityPermissionsImplementation.d.ts +974 -0
  299. package/dist/generated/abi/DataPortabilityPermissionsImplementation.js +1274 -0
  300. package/dist/generated/abi/DataPortabilityPermissionsImplementation.js.map +1 -0
  301. package/dist/generated/abi/DataPortabilityServersImplementation.cjs +1419 -0
  302. package/dist/generated/abi/DataPortabilityServersImplementation.cjs.map +1 -0
  303. package/dist/generated/abi/DataPortabilityServersImplementation.d.ts +1071 -0
  304. package/dist/generated/abi/DataPortabilityServersImplementation.js +1395 -0
  305. package/dist/generated/abi/DataPortabilityServersImplementation.js.map +1 -0
  306. package/dist/generated/abi/DataRefinerRegistryImplementation.cjs +984 -0
  307. package/dist/generated/abi/DataRefinerRegistryImplementation.cjs.map +1 -0
  308. package/dist/generated/abi/DataRefinerRegistryImplementation.d.ts +736 -0
  309. package/dist/generated/abi/DataRefinerRegistryImplementation.js +960 -0
  310. package/dist/generated/abi/DataRefinerRegistryImplementation.js.map +1 -0
  311. package/dist/generated/abi/DataRegistryImplementation.cjs +1328 -0
  312. package/dist/generated/abi/DataRegistryImplementation.cjs.map +1 -0
  313. package/dist/generated/abi/DataRegistryImplementation.d.ts +1003 -0
  314. package/dist/generated/abi/DataRegistryImplementation.js +1304 -0
  315. package/dist/generated/abi/DataRegistryImplementation.js.map +1 -0
  316. package/dist/generated/abi/QueryEngineImplementation.cjs +1319 -0
  317. package/dist/generated/abi/QueryEngineImplementation.cjs.map +1 -0
  318. package/dist/generated/abi/QueryEngineImplementation.d.ts +1000 -0
  319. package/dist/generated/abi/QueryEngineImplementation.js +1295 -0
  320. package/dist/generated/abi/QueryEngineImplementation.js.map +1 -0
  321. package/dist/generated/abi/SwapHelperImplementation.cjs +976 -0
  322. package/dist/generated/abi/SwapHelperImplementation.cjs.map +1 -0
  323. package/dist/generated/abi/SwapHelperImplementation.d.ts +728 -0
  324. package/dist/generated/abi/SwapHelperImplementation.js +952 -0
  325. package/dist/generated/abi/SwapHelperImplementation.js.map +1 -0
  326. package/dist/generated/abi/TeePoolDedicatedGpuImplementation.cjs +936 -0
  327. package/dist/generated/abi/TeePoolDedicatedGpuImplementation.cjs.map +1 -0
  328. package/dist/generated/abi/TeePoolDedicatedGpuImplementation.d.ts +700 -0
  329. package/dist/generated/abi/TeePoolDedicatedGpuImplementation.js +912 -0
  330. package/dist/generated/abi/TeePoolDedicatedGpuImplementation.js.map +1 -0
  331. package/dist/generated/abi/TeePoolDedicatedStandardImplementation.cjs +936 -0
  332. package/dist/generated/abi/TeePoolDedicatedStandardImplementation.cjs.map +1 -0
  333. package/dist/generated/abi/TeePoolDedicatedStandardImplementation.d.ts +700 -0
  334. package/dist/generated/abi/TeePoolDedicatedStandardImplementation.js +912 -0
  335. package/dist/generated/abi/TeePoolDedicatedStandardImplementation.js.map +1 -0
  336. package/dist/generated/abi/TeePoolEphemeralStandardImplementation.cjs +936 -0
  337. package/dist/generated/abi/TeePoolEphemeralStandardImplementation.cjs.map +1 -0
  338. package/dist/generated/abi/TeePoolEphemeralStandardImplementation.d.ts +700 -0
  339. package/dist/generated/abi/TeePoolEphemeralStandardImplementation.js +912 -0
  340. package/dist/generated/abi/TeePoolEphemeralStandardImplementation.js.map +1 -0
  341. package/dist/generated/abi/TeePoolImplementation.cjs +1313 -0
  342. package/dist/generated/abi/TeePoolImplementation.cjs.map +1 -0
  343. package/dist/generated/abi/TeePoolImplementation.d.ts +992 -0
  344. package/dist/generated/abi/TeePoolImplementation.js +1289 -0
  345. package/dist/generated/abi/TeePoolImplementation.js.map +1 -0
  346. package/dist/generated/abi/TeePoolPersistentGpuImplementation.cjs +936 -0
  347. package/dist/generated/abi/TeePoolPersistentGpuImplementation.cjs.map +1 -0
  348. package/dist/generated/abi/TeePoolPersistentGpuImplementation.d.ts +700 -0
  349. package/dist/generated/abi/TeePoolPersistentGpuImplementation.js +912 -0
  350. package/dist/generated/abi/TeePoolPersistentGpuImplementation.js.map +1 -0
  351. package/dist/generated/abi/TeePoolPersistentStandardImplementation.cjs +936 -0
  352. package/dist/generated/abi/TeePoolPersistentStandardImplementation.cjs.map +1 -0
  353. package/dist/generated/abi/TeePoolPersistentStandardImplementation.d.ts +700 -0
  354. package/dist/generated/abi/TeePoolPersistentStandardImplementation.js +912 -0
  355. package/dist/generated/abi/TeePoolPersistentStandardImplementation.js.map +1 -0
  356. package/dist/generated/abi/TeePoolPhalaImplementation.cjs +1313 -0
  357. package/dist/generated/abi/TeePoolPhalaImplementation.cjs.map +1 -0
  358. package/dist/generated/abi/TeePoolPhalaImplementation.d.ts +992 -0
  359. package/dist/generated/abi/TeePoolPhalaImplementation.js +1289 -0
  360. package/dist/generated/abi/TeePoolPhalaImplementation.js.map +1 -0
  361. package/dist/generated/abi/VanaEpochImplementation.cjs +1383 -0
  362. package/dist/generated/abi/VanaEpochImplementation.cjs.map +1 -0
  363. package/dist/generated/abi/VanaEpochImplementation.d.ts +1050 -0
  364. package/dist/generated/abi/VanaEpochImplementation.js +1359 -0
  365. package/dist/generated/abi/VanaEpochImplementation.js.map +1 -0
  366. package/dist/generated/abi/VanaPoolEntityImplementation.cjs +1191 -0
  367. package/dist/generated/abi/VanaPoolEntityImplementation.cjs.map +1 -0
  368. package/dist/generated/abi/VanaPoolEntityImplementation.d.ts +899 -0
  369. package/dist/generated/abi/VanaPoolEntityImplementation.js +1167 -0
  370. package/dist/generated/abi/VanaPoolEntityImplementation.js.map +1 -0
  371. package/dist/generated/abi/VanaPoolStakingImplementation.cjs +1033 -0
  372. package/dist/generated/abi/VanaPoolStakingImplementation.cjs.map +1 -0
  373. package/dist/generated/abi/VanaPoolStakingImplementation.d.ts +776 -0
  374. package/dist/generated/abi/VanaPoolStakingImplementation.js +1009 -0
  375. package/dist/generated/abi/VanaPoolStakingImplementation.js.map +1 -0
  376. package/dist/generated/abi/VanaPoolTreasuryImplementation.cjs +538 -0
  377. package/dist/generated/abi/VanaPoolTreasuryImplementation.cjs.map +1 -0
  378. package/dist/generated/abi/VanaPoolTreasuryImplementation.d.ts +393 -0
  379. package/dist/generated/abi/VanaPoolTreasuryImplementation.js +514 -0
  380. package/dist/generated/abi/VanaPoolTreasuryImplementation.js.map +1 -0
  381. package/dist/generated/abi/index.cjs +177 -0
  382. package/dist/generated/abi/index.cjs.map +1 -0
  383. package/dist/{index.node.d.cts → generated/abi/index.d.ts} +26941 -37486
  384. package/dist/generated/abi/index.js +120 -0
  385. package/dist/generated/abi/index.js.map +1 -0
  386. package/dist/generated/event-types.cjs +17 -0
  387. package/dist/generated/event-types.cjs.map +1 -0
  388. package/dist/generated/event-types.d.ts +860 -0
  389. package/dist/generated/event-types.js +1 -0
  390. package/dist/generated/event-types.js.map +1 -0
  391. package/dist/generated/eventRegistry.cjs +3375 -0
  392. package/dist/generated/eventRegistry.cjs.map +1 -0
  393. package/dist/generated/eventRegistry.d.ts +14 -0
  394. package/dist/generated/eventRegistry.js +3350 -0
  395. package/dist/generated/eventRegistry.js.map +1 -0
  396. package/dist/generated/server/server-exports.cjs +45 -0
  397. package/dist/generated/server/server-exports.cjs.map +1 -0
  398. package/dist/generated/server/server-exports.d.ts +36 -0
  399. package/dist/generated/server/server-exports.js +19 -0
  400. package/dist/generated/server/server-exports.js.map +1 -0
  401. package/dist/generated/server/server.cjs +17 -0
  402. package/dist/generated/server/server.cjs.map +1 -0
  403. package/dist/generated/server/server.d.ts +907 -0
  404. package/dist/generated/server/server.js +1 -0
  405. package/dist/generated/server/server.js.map +1 -0
  406. package/dist/generated/subgraph.cjs +1440 -0
  407. package/dist/generated/subgraph.cjs.map +1 -0
  408. package/dist/generated/subgraph.d.ts +6113 -0
  409. package/dist/generated/subgraph.js +1404 -0
  410. package/dist/generated/subgraph.js.map +1 -0
  411. package/dist/index.browser.d.ts +48 -37223
  412. package/dist/index.browser.js +86 -46352
  413. package/dist/index.browser.js.map +1 -1
  414. package/dist/index.cjs +5 -0
  415. package/dist/index.cjs.map +1 -0
  416. package/dist/index.d.ts +0 -0
  417. package/dist/index.js +4 -0
  418. package/dist/index.js.map +1 -0
  419. package/dist/index.node.cjs +123 -46839
  420. package/dist/index.node.cjs.map +1 -1
  421. package/dist/index.node.d.ts +92 -37358
  422. package/dist/index.node.js +103 -46726
  423. package/dist/index.node.js.map +1 -1
  424. package/dist/lib/__tests__/redisAtomicStore.test.d.ts +1 -0
  425. package/dist/lib/redisAtomicStore.cjs +201 -0
  426. package/dist/lib/redisAtomicStore.cjs.map +1 -0
  427. package/dist/lib/redisAtomicStore.d.ts +120 -0
  428. package/dist/lib/redisAtomicStore.js +177 -0
  429. package/dist/lib/redisAtomicStore.js.map +1 -0
  430. package/dist/node.cjs +2 -321
  431. package/dist/node.cjs.map +1 -1
  432. package/dist/node.d.ts +42 -1
  433. package/dist/node.js +1 -307
  434. package/dist/node.js.map +1 -1
  435. package/dist/platform/browser-only.cjs +37 -0
  436. package/dist/platform/browser-only.cjs.map +1 -0
  437. package/dist/platform/browser-only.d.ts +22 -0
  438. package/dist/platform/browser-only.js +12 -0
  439. package/dist/platform/browser-only.js.map +1 -0
  440. package/dist/platform/browser-only.test.d.ts +1 -0
  441. package/dist/platform/browser-safe.cjs +57 -0
  442. package/dist/platform/browser-safe.cjs.map +1 -0
  443. package/dist/platform/browser-safe.d.ts +29 -0
  444. package/dist/platform/browser-safe.js +31 -0
  445. package/dist/platform/browser-safe.js.map +1 -0
  446. package/dist/platform/browser-safe.test.d.ts +1 -0
  447. package/dist/platform/browser.cjs +488 -0
  448. package/dist/platform/browser.cjs.map +1 -0
  449. package/dist/platform/browser.d.ts +291 -0
  450. package/dist/platform/browser.js +454 -0
  451. package/dist/platform/browser.js.map +1 -0
  452. package/dist/platform/browser.test.d.ts +1 -0
  453. package/dist/platform/index.cjs +50 -0
  454. package/dist/platform/index.cjs.map +1 -0
  455. package/dist/platform/index.d.ts +11 -0
  456. package/dist/platform/index.js +27 -0
  457. package/dist/platform/index.js.map +1 -0
  458. package/dist/platform/interface.cjs +17 -0
  459. package/dist/platform/interface.cjs.map +1 -0
  460. package/dist/platform/interface.d.ts +409 -0
  461. package/dist/platform/interface.js +1 -0
  462. package/dist/platform/interface.js.map +1 -0
  463. package/dist/platform/node.cjs +512 -0
  464. package/dist/platform/node.cjs.map +1 -0
  465. package/dist/platform/node.d.ts +86 -0
  466. package/dist/platform/node.js +481 -0
  467. package/dist/platform/node.js.map +1 -0
  468. package/dist/platform/ports/openpgp-port.cjs +74 -0
  469. package/dist/platform/ports/openpgp-port.cjs.map +1 -0
  470. package/dist/platform/ports/openpgp-port.d.ts +13 -0
  471. package/dist/platform/ports/openpgp-port.js +59 -0
  472. package/dist/platform/ports/openpgp-port.js.map +1 -0
  473. package/dist/platform/ports/pgp-port.cjs +17 -0
  474. package/dist/platform/ports/pgp-port.cjs.map +1 -0
  475. package/dist/platform/ports/pgp-port.d.ts +35 -0
  476. package/dist/platform/ports/pgp-port.js +1 -0
  477. package/dist/platform/ports/pgp-port.js.map +1 -0
  478. package/dist/platform/shared/error-utils.cjs +43 -0
  479. package/dist/platform/shared/error-utils.cjs.map +1 -0
  480. package/dist/platform/shared/error-utils.d.ts +23 -0
  481. package/dist/platform/shared/error-utils.js +18 -0
  482. package/dist/platform/shared/error-utils.js.map +1 -0
  483. package/dist/platform/shared/pgp-utils.cjs +55 -0
  484. package/dist/platform/shared/pgp-utils.cjs.map +1 -0
  485. package/dist/platform/shared/pgp-utils.d.ts +59 -0
  486. package/dist/platform/shared/pgp-utils.js +29 -0
  487. package/dist/platform/shared/pgp-utils.js.map +1 -0
  488. package/dist/platform/shared/stream-utils.cjs +49 -0
  489. package/dist/platform/shared/stream-utils.cjs.map +1 -0
  490. package/dist/platform/shared/stream-utils.d.ts +14 -0
  491. package/dist/platform/shared/stream-utils.js +25 -0
  492. package/dist/platform/shared/stream-utils.js.map +1 -0
  493. package/dist/platform/utils.cjs +114 -0
  494. package/dist/platform/utils.cjs.map +1 -0
  495. package/dist/platform/utils.d.ts +49 -0
  496. package/dist/platform/utils.js +76 -0
  497. package/dist/platform/utils.js.map +1 -0
  498. package/dist/platform/utils.test.d.ts +1 -0
  499. package/dist/platform.browser.d.ts +6 -57
  500. package/dist/platform.browser.js +10 -379
  501. package/dist/platform.browser.js.map +1 -1
  502. package/dist/platform.cjs +14 -708
  503. package/dist/platform.cjs.map +1 -1
  504. package/dist/platform.d.ts +11 -2
  505. package/dist/platform.js +14 -694
  506. package/dist/platform.js.map +1 -1
  507. package/dist/platform.node.cjs +14 -708
  508. package/dist/platform.node.cjs.map +1 -1
  509. package/dist/platform.node.d.ts +7 -102
  510. package/dist/platform.node.js +14 -694
  511. package/dist/platform.node.js.map +1 -1
  512. package/dist/schemas/dataSchema.schema.json +53 -0
  513. package/dist/schemas/grantFile.schema.json +43 -0
  514. package/dist/server/relayerHandler.cjs +452 -0
  515. package/dist/server/relayerHandler.cjs.map +1 -0
  516. package/dist/server/relayerHandler.d.ts +69 -0
  517. package/dist/server/relayerHandler.js +428 -0
  518. package/dist/server/relayerHandler.js.map +1 -0
  519. package/dist/storage/index.cjs +47 -0
  520. package/dist/storage/index.cjs.map +1 -0
  521. package/dist/storage/index.d.ts +57 -0
  522. package/dist/storage/index.js +17 -0
  523. package/dist/storage/index.js.map +1 -0
  524. package/dist/storage/manager.cjs +272 -0
  525. package/dist/storage/manager.cjs.map +1 -0
  526. package/dist/storage/manager.d.ts +241 -0
  527. package/dist/storage/manager.js +248 -0
  528. package/dist/storage/manager.js.map +1 -0
  529. package/dist/storage/providers/callback-storage.cjs +248 -0
  530. package/dist/storage/providers/callback-storage.cjs.map +1 -0
  531. package/dist/storage/providers/callback-storage.d.ts +183 -0
  532. package/dist/storage/providers/callback-storage.js +226 -0
  533. package/dist/storage/providers/callback-storage.js.map +1 -0
  534. package/dist/storage/providers/dropbox.cjs +237 -0
  535. package/dist/storage/providers/dropbox.cjs.map +1 -0
  536. package/dist/storage/providers/dropbox.d.ts +39 -0
  537. package/dist/storage/providers/dropbox.js +215 -0
  538. package/dist/storage/providers/dropbox.js.map +1 -0
  539. package/dist/storage/providers/dropbox.test.d.ts +1 -0
  540. package/dist/storage/providers/google-drive.cjs +516 -0
  541. package/dist/storage/providers/google-drive.cjs.map +1 -0
  542. package/dist/storage/providers/google-drive.d.ts +152 -0
  543. package/dist/storage/providers/google-drive.js +494 -0
  544. package/dist/storage/providers/google-drive.js.map +1 -0
  545. package/dist/storage/providers/google-drive.test.d.ts +1 -0
  546. package/dist/storage/providers/ipfs.cjs +283 -0
  547. package/dist/storage/providers/ipfs.cjs.map +1 -0
  548. package/dist/storage/providers/ipfs.d.ts +160 -0
  549. package/dist/storage/providers/ipfs.js +261 -0
  550. package/dist/storage/providers/ipfs.js.map +1 -0
  551. package/dist/storage/providers/pinata.cjs +339 -0
  552. package/dist/storage/providers/pinata.cjs.map +1 -0
  553. package/dist/storage/providers/pinata.d.ts +168 -0
  554. package/dist/storage/providers/pinata.js +317 -0
  555. package/dist/storage/providers/pinata.js.map +1 -0
  556. package/dist/storage/tests/callbackStorage.test.d.ts +1 -0
  557. package/dist/storage/tests/googleDriveStorage.test.d.ts +1 -0
  558. package/dist/storage/tests/ipfsStorage.test.d.ts +1 -0
  559. package/dist/storage/tests/pinataStorage.test.d.ts +1 -0
  560. package/dist/storage/tests/storageManager.test.d.ts +1 -0
  561. package/dist/tests/abi.test.d.ts +1 -0
  562. package/dist/tests/chains-definitions.test.d.ts +1 -0
  563. package/dist/tests/core-encryption.test.d.ts +1 -0
  564. package/dist/tests/core-extended.test.d.ts +1 -0
  565. package/dist/tests/core-generics-coverage.test.d.ts +1 -0
  566. package/dist/tests/coverage-boost.test.d.ts +1 -0
  567. package/dist/tests/crypto-cross-platform-compatibility.test.d.ts +1 -0
  568. package/dist/tests/data-addfile-permissions-schema.test.d.ts +1 -0
  569. package/dist/tests/data-additional-methods.test.d.ts +1 -0
  570. package/dist/tests/data-controller-edge-cases.test.d.ts +1 -0
  571. package/dist/tests/data-ipfs-gateways.test.d.ts +1 -0
  572. package/dist/tests/data-relayer.test.d.ts +1 -0
  573. package/dist/tests/data-schema-validation.test.d.ts +1 -0
  574. package/dist/tests/data-simple-methods.test.d.ts +1 -0
  575. package/dist/tests/data-upload-owner-validation.test.d.ts +1 -0
  576. package/dist/tests/data.test.d.ts +1 -0
  577. package/dist/tests/demo-integration.test.d.ts +1 -0
  578. package/dist/tests/demo-trusted-server-integration.test.d.ts +1 -0
  579. package/dist/tests/download-relayer.test.d.ts +1 -0
  580. package/dist/tests/dual-mode-permissions.test.d.ts +1 -0
  581. package/dist/tests/dual-mode-trusted-servers.test.d.ts +1 -0
  582. package/dist/tests/encryption-correct-implementation.test.d.ts +1 -0
  583. package/dist/tests/encryption-coverage.test.d.ts +1 -0
  584. package/dist/tests/encryption-edge-cases.test.d.ts +1 -0
  585. package/dist/tests/encryption-utils-updated.test.d.ts +1 -0
  586. package/dist/tests/errors-coverage.test.d.ts +1 -0
  587. package/dist/tests/errors.test.d.ts +1 -0
  588. package/dist/tests/factories/mockFactory.d.ts +316 -0
  589. package/dist/tests/fakes/FakeStorageManager.d.ts +200 -0
  590. package/dist/tests/fakes/FakeStorageManager.test.d.ts +1 -0
  591. package/dist/tests/fakes/FakeWaitForTransactionEvents.d.ts +170 -0
  592. package/dist/tests/fakes/FakeWaitForTransactionEvents.test.d.ts +1 -0
  593. package/dist/tests/fakes/fake-pgp-port.d.ts +13 -0
  594. package/dist/tests/grantValidation-edge-cases.test.d.ts +1 -0
  595. package/dist/tests/grantValidation-unreachable-branch.test.d.ts +1 -0
  596. package/dist/tests/helper-methods.test.d.ts +1 -0
  597. package/dist/tests/helpers/platformTestHelpers.d.ts +106 -0
  598. package/dist/tests/helpers/typedMocks.d.ts +64 -0
  599. package/dist/tests/index-browser.test.d.ts +1 -0
  600. package/dist/tests/index-node.test.d.ts +1 -0
  601. package/dist/tests/index.test.d.ts +1 -0
  602. package/dist/tests/mocks/platformAdapter.d.ts +12 -0
  603. package/dist/tests/new-permissions-methods.test.d.ts +1 -0
  604. package/dist/tests/no-buffer-browser.test.d.ts +1 -0
  605. package/dist/tests/permissions-grantee.test.d.ts +1 -0
  606. package/dist/tests/permissions-revoke-relayer.test.d.ts +1 -0
  607. package/dist/tests/permissions-schema-validation.test.d.ts +1 -0
  608. package/dist/tests/permissions-server-files.test.d.ts +1 -0
  609. package/dist/tests/permissions-transaction-options.test.d.ts +1 -0
  610. package/dist/tests/permissions-trust-servers.test.d.ts +1 -0
  611. package/dist/tests/permissions.test.d.ts +1 -0
  612. package/dist/tests/personal.test.d.ts +1 -0
  613. package/dist/tests/platform-browser.test.d.ts +1 -0
  614. package/dist/tests/platform-crypto-expanded.test.d.ts +1 -0
  615. package/dist/tests/platform-crypto.test.d.ts +1 -0
  616. package/dist/tests/platform-index.test.d.ts +1 -0
  617. package/dist/tests/platform-node.test.d.ts +1 -0
  618. package/dist/tests/platform-shared-utils.test.d.ts +1 -0
  619. package/dist/tests/platform-updated.test.d.ts +1 -0
  620. package/dist/tests/protocol-additional-methods.test.d.ts +1 -0
  621. package/dist/tests/protocol.test.d.ts +1 -0
  622. package/dist/tests/read-only-mode.test.d.ts +1 -0
  623. package/dist/tests/relayer-integration.test.d.ts +1 -0
  624. package/dist/tests/relayer-unified.test.d.ts +1 -0
  625. package/dist/tests/schemas.test.d.ts +1 -0
  626. package/dist/tests/server-relayer-handler.test.d.ts +1 -0
  627. package/dist/tests/setup.d.ts +7 -0
  628. package/dist/tests/signatureFormatter.test.d.ts +1 -0
  629. package/dist/tests/trusted-server-queries.test.d.ts +1 -0
  630. package/dist/tests/typedDataConverter.test.d.ts +1 -0
  631. package/dist/tests/types-contracts.test.d.ts +1 -0
  632. package/dist/tests/types-data.test.d.ts +1 -0
  633. package/dist/tests/types-external-apis.test.d.ts +1 -0
  634. package/dist/tests/types-generics.test.d.ts +1 -0
  635. package/dist/tests/types-permissions.test.d.ts +1 -0
  636. package/dist/tests/types-upload-params.test.d.ts +1 -0
  637. package/dist/tests/types.test.d.ts +1 -0
  638. package/dist/tests/utils-formatters.test.d.ts +1 -0
  639. package/dist/tests/utils-grantFiles-edge-cases.test.d.ts +1 -0
  640. package/dist/tests/utils-grantFiles-validation.test.d.ts +1 -0
  641. package/dist/tests/utils-grantFiles.test.d.ts +1 -0
  642. package/dist/tests/utils-grantValidation-consolidated.test.d.ts +1 -0
  643. package/dist/tests/utils-grants.test.d.ts +1 -0
  644. package/dist/tests/utils-ipfs-additional.test.d.ts +1 -0
  645. package/dist/tests/utils-ipfs.test.d.ts +4 -0
  646. package/dist/tests/utils-schemaValidation.test.d.ts +1 -0
  647. package/dist/tests/vana.test.d.ts +1 -0
  648. package/dist/tests/wallet-crypto-compatibility.test.d.ts +1 -0
  649. package/dist/types/atomicStore.cjs +31 -0
  650. package/dist/types/atomicStore.cjs.map +1 -0
  651. package/dist/types/atomicStore.d.ts +236 -0
  652. package/dist/types/atomicStore.js +7 -0
  653. package/dist/types/atomicStore.js.map +1 -0
  654. package/dist/types/blockchain.cjs +17 -0
  655. package/dist/types/blockchain.cjs.map +1 -0
  656. package/dist/types/blockchain.d.ts +85 -0
  657. package/dist/types/blockchain.js +1 -0
  658. package/dist/types/blockchain.js.map +1 -0
  659. package/dist/types/chains-additional.test.d.ts +1 -0
  660. package/dist/types/chains.cjs +36 -0
  661. package/dist/types/chains.cjs.map +1 -0
  662. package/dist/types/chains.d.ts +98 -0
  663. package/dist/types/chains.js +11 -0
  664. package/dist/types/chains.js.map +1 -0
  665. package/dist/types/config.cjs +51 -0
  666. package/dist/types/config.cjs.map +1 -0
  667. package/dist/types/config.d.ts +720 -0
  668. package/dist/types/config.js +23 -0
  669. package/dist/types/config.js.map +1 -0
  670. package/dist/types/contracts.cjs +17 -0
  671. package/dist/types/contracts.cjs.map +1 -0
  672. package/dist/types/contracts.d.ts +129 -0
  673. package/dist/types/contracts.js +1 -0
  674. package/dist/types/contracts.js.map +1 -0
  675. package/dist/types/controller-context.cjs +17 -0
  676. package/dist/types/controller-context.cjs.map +1 -0
  677. package/dist/types/controller-context.d.ts +68 -0
  678. package/dist/types/controller-context.js +1 -0
  679. package/dist/types/controller-context.js.map +1 -0
  680. package/dist/types/data.cjs +17 -0
  681. package/dist/types/data.cjs.map +1 -0
  682. package/dist/types/data.d.ts +763 -0
  683. package/dist/types/data.js +1 -0
  684. package/dist/types/data.js.map +1 -0
  685. package/dist/types/eccrypto-js.d.cjs +2 -0
  686. package/dist/types/eccrypto-js.d.cjs.map +1 -0
  687. package/dist/types/eccrypto-js.d.js +1 -0
  688. package/dist/types/eccrypto-js.d.js.map +1 -0
  689. package/dist/types/external-apis.cjs +61 -0
  690. package/dist/types/external-apis.cjs.map +1 -0
  691. package/dist/types/external-apis.d.ts +184 -0
  692. package/dist/types/external-apis.js +34 -0
  693. package/dist/types/external-apis.js.map +1 -0
  694. package/dist/types/generics.cjs +17 -0
  695. package/dist/types/generics.cjs.map +1 -0
  696. package/dist/types/generics.d.ts +518 -0
  697. package/dist/types/generics.js +1 -0
  698. package/dist/types/generics.js.map +1 -0
  699. package/dist/types/index.cjs +65 -0
  700. package/dist/types/index.cjs.map +1 -0
  701. package/dist/types/index.d.ts +48 -0
  702. package/dist/types/index.js +42 -0
  703. package/dist/types/index.js.map +1 -0
  704. package/dist/types/operationStore.cjs +17 -0
  705. package/dist/types/operationStore.cjs.map +1 -0
  706. package/dist/types/operationStore.d.ts +171 -0
  707. package/dist/types/operationStore.js +1 -0
  708. package/dist/types/operationStore.js.map +1 -0
  709. package/dist/types/operations.cjs +53 -0
  710. package/dist/types/operations.cjs.map +1 -0
  711. package/dist/types/operations.d.ts +204 -0
  712. package/dist/types/operations.js +26 -0
  713. package/dist/types/operations.js.map +1 -0
  714. package/dist/types/options.cjs +17 -0
  715. package/dist/types/options.cjs.map +1 -0
  716. package/dist/types/options.d.ts +308 -0
  717. package/dist/types/options.js +1 -0
  718. package/dist/types/options.js.map +1 -0
  719. package/dist/types/permissions.cjs +17 -0
  720. package/dist/types/permissions.cjs.map +1 -0
  721. package/dist/types/permissions.d.ts +953 -0
  722. package/dist/types/permissions.js +1 -0
  723. package/dist/types/permissions.js.map +1 -0
  724. package/dist/types/personal.cjs +17 -0
  725. package/dist/types/personal.cjs.map +1 -0
  726. package/dist/types/personal.d.ts +174 -0
  727. package/dist/types/personal.js +1 -0
  728. package/dist/types/personal.js.map +1 -0
  729. package/dist/types/relayer.cjs +17 -0
  730. package/dist/types/relayer.cjs.map +1 -0
  731. package/dist/types/relayer.d.ts +552 -0
  732. package/dist/types/relayer.js +1 -0
  733. package/dist/types/relayer.js.map +1 -0
  734. package/dist/types/storage.cjs +39 -0
  735. package/dist/types/storage.cjs.map +1 -0
  736. package/dist/types/storage.d.ts +117 -0
  737. package/dist/types/storage.js +15 -0
  738. package/dist/types/storage.js.map +1 -0
  739. package/dist/types/transactionResults.cjs +17 -0
  740. package/dist/types/transactionResults.cjs.map +1 -0
  741. package/dist/types/transactionResults.d.ts +193 -0
  742. package/dist/types/transactionResults.js +1 -0
  743. package/dist/types/transactionResults.js.map +1 -0
  744. package/dist/types/utils.cjs +17 -0
  745. package/dist/types/utils.cjs.map +1 -0
  746. package/dist/types/utils.d.ts +771 -0
  747. package/dist/types/utils.js +1 -0
  748. package/dist/types/utils.js.map +1 -0
  749. package/dist/types.cjs +23 -0
  750. package/dist/types.cjs.map +1 -0
  751. package/dist/types.d.ts +30 -0
  752. package/dist/types.js +2 -0
  753. package/dist/types.js.map +1 -0
  754. package/dist/utils/__tests__/chainQuery.test.d.ts +1 -0
  755. package/dist/utils/__tests__/parseTransaction.test.d.ts +1 -0
  756. package/dist/utils/__tests__/pojo-serialization.test.d.ts +1 -0
  757. package/dist/utils/__tests__/signatureCache.test.d.ts +1 -0
  758. package/dist/utils/__tests__/subgraphConsistency.test.d.ts +4 -0
  759. package/dist/utils/__tests__/subgraphPagination.test.d.ts +4 -0
  760. package/dist/utils/__tests__/transaction-edge-cases.test.d.ts +1 -0
  761. package/dist/utils/__tests__/transactionHelpers.test.d.ts +1 -0
  762. package/dist/utils/__tests__/urlResolver.test.d.ts +4 -0
  763. package/dist/utils/blockchain/registry.cjs +81 -0
  764. package/dist/utils/blockchain/registry.cjs.map +1 -0
  765. package/dist/utils/blockchain/registry.d.ts +32 -0
  766. package/dist/utils/blockchain/registry.js +56 -0
  767. package/dist/utils/blockchain/registry.js.map +1 -0
  768. package/dist/utils/blockchain/registry.test.d.ts +1 -0
  769. package/dist/utils/chainQuery.cjs +107 -0
  770. package/dist/utils/chainQuery.cjs.map +1 -0
  771. package/dist/utils/chainQuery.d.ts +31 -0
  772. package/dist/utils/chainQuery.js +82 -0
  773. package/dist/utils/chainQuery.js.map +1 -0
  774. package/dist/utils/crypto-utils.cjs +108 -0
  775. package/dist/utils/crypto-utils.cjs.map +1 -0
  776. package/dist/utils/crypto-utils.d.ts +100 -0
  777. package/dist/utils/crypto-utils.js +76 -0
  778. package/dist/utils/crypto-utils.js.map +1 -0
  779. package/dist/utils/crypto-utils.test.d.ts +1 -0
  780. package/dist/utils/download.cjs +69 -0
  781. package/dist/utils/download.cjs.map +1 -0
  782. package/dist/utils/download.d.ts +40 -0
  783. package/dist/utils/download.js +45 -0
  784. package/dist/utils/download.js.map +1 -0
  785. package/dist/utils/encoding.cjs +66 -0
  786. package/dist/utils/encoding.cjs.map +1 -0
  787. package/dist/utils/encoding.d.ts +52 -0
  788. package/dist/utils/encoding.js +39 -0
  789. package/dist/utils/encoding.js.map +1 -0
  790. package/dist/utils/encoding.test.d.ts +1 -0
  791. package/dist/utils/encryption.cjs +176 -0
  792. package/dist/utils/encryption.cjs.map +1 -0
  793. package/dist/utils/encryption.d.ts +271 -0
  794. package/dist/utils/encryption.js +142 -0
  795. package/dist/utils/encryption.js.map +1 -0
  796. package/dist/utils/formatters.cjs +55 -0
  797. package/dist/utils/formatters.cjs.map +1 -0
  798. package/dist/utils/formatters.d.ts +118 -0
  799. package/dist/utils/formatters.js +28 -0
  800. package/dist/utils/formatters.js.map +1 -0
  801. package/dist/utils/grantFiles.cjs +181 -0
  802. package/dist/utils/grantFiles.cjs.map +1 -0
  803. package/dist/utils/grantFiles.d.ts +172 -0
  804. package/dist/utils/grantFiles.js +143 -0
  805. package/dist/utils/grantFiles.js.map +1 -0
  806. package/dist/utils/grantValidation.cjs +243 -0
  807. package/dist/utils/grantValidation.cjs.map +1 -0
  808. package/dist/utils/grantValidation.d.ts +226 -0
  809. package/dist/utils/grantValidation.js +201 -0
  810. package/dist/utils/grantValidation.js.map +1 -0
  811. package/dist/utils/grants.cjs +108 -0
  812. package/dist/utils/grants.cjs.map +1 -0
  813. package/dist/utils/grants.d.ts +148 -0
  814. package/dist/utils/grants.js +82 -0
  815. package/dist/utils/grants.js.map +1 -0
  816. package/dist/utils/ipfs.cjs +128 -0
  817. package/dist/utils/ipfs.cjs.map +1 -0
  818. package/dist/utils/ipfs.d.ts +88 -0
  819. package/dist/utils/ipfs.js +97 -0
  820. package/dist/utils/ipfs.js.map +1 -0
  821. package/dist/utils/lazy-import.cjs +38 -0
  822. package/dist/utils/lazy-import.cjs.map +1 -0
  823. package/dist/utils/lazy-import.d.ts +43 -0
  824. package/dist/utils/lazy-import.js +14 -0
  825. package/dist/utils/lazy-import.js.map +1 -0
  826. package/dist/utils/multicall.cjs +233 -0
  827. package/dist/utils/multicall.cjs.map +1 -0
  828. package/dist/utils/multicall.d.ts +126 -0
  829. package/dist/utils/multicall.js +208 -0
  830. package/dist/utils/multicall.js.map +1 -0
  831. package/dist/utils/parseTransactionPojo.cjs +87 -0
  832. package/dist/utils/parseTransactionPojo.cjs.map +1 -0
  833. package/dist/utils/parseTransactionPojo.d.ts +31 -0
  834. package/dist/utils/parseTransactionPojo.js +63 -0
  835. package/dist/utils/parseTransactionPojo.js.map +1 -0
  836. package/dist/utils/schemaValidation.cjs +258 -0
  837. package/dist/utils/schemaValidation.cjs.map +1 -0
  838. package/dist/utils/schemaValidation.d.ts +168 -0
  839. package/dist/utils/schemaValidation.js +219 -0
  840. package/dist/utils/schemaValidation.js.map +1 -0
  841. package/dist/utils/signatureCache.cjs +192 -0
  842. package/dist/utils/signatureCache.cjs.map +1 -0
  843. package/dist/utils/signatureCache.d.ts +172 -0
  844. package/dist/utils/signatureCache.js +167 -0
  845. package/dist/utils/signatureCache.js.map +1 -0
  846. package/dist/utils/signatureFormatter.cjs +42 -0
  847. package/dist/utils/signatureFormatter.cjs.map +1 -0
  848. package/dist/utils/signatureFormatter.d.ts +36 -0
  849. package/dist/utils/signatureFormatter.js +18 -0
  850. package/dist/utils/signatureFormatter.js.map +1 -0
  851. package/dist/utils/subgraphConsistency.cjs +184 -0
  852. package/dist/utils/subgraphConsistency.cjs.map +1 -0
  853. package/dist/utils/subgraphConsistency.d.ts +65 -0
  854. package/dist/utils/subgraphConsistency.js +155 -0
  855. package/dist/utils/subgraphConsistency.js.map +1 -0
  856. package/dist/utils/subgraphMetaCache.cjs +101 -0
  857. package/dist/utils/subgraphMetaCache.cjs.map +1 -0
  858. package/dist/utils/subgraphMetaCache.d.ts +56 -0
  859. package/dist/utils/subgraphMetaCache.js +76 -0
  860. package/dist/utils/subgraphMetaCache.js.map +1 -0
  861. package/dist/utils/subgraphPagination.cjs +104 -0
  862. package/dist/utils/subgraphPagination.cjs.map +1 -0
  863. package/dist/utils/subgraphPagination.d.ts +78 -0
  864. package/dist/utils/subgraphPagination.js +78 -0
  865. package/dist/utils/subgraphPagination.js.map +1 -0
  866. package/dist/utils/tests/multicall.test.d.ts +1 -0
  867. package/dist/utils/transactionHelpers.cjs +54 -0
  868. package/dist/utils/transactionHelpers.cjs.map +1 -0
  869. package/dist/utils/transactionHelpers.d.ts +80 -0
  870. package/dist/utils/transactionHelpers.js +29 -0
  871. package/dist/utils/transactionHelpers.js.map +1 -0
  872. package/dist/utils/typeGuards.cjs +109 -0
  873. package/dist/utils/typeGuards.cjs.map +1 -0
  874. package/dist/utils/typeGuards.d.ts +138 -0
  875. package/dist/utils/typeGuards.js +74 -0
  876. package/dist/utils/typeGuards.js.map +1 -0
  877. package/dist/utils/typedDataConverter.cjs +43 -0
  878. package/dist/utils/typedDataConverter.cjs.map +1 -0
  879. package/dist/utils/typedDataConverter.d.ts +46 -0
  880. package/dist/utils/typedDataConverter.js +19 -0
  881. package/dist/utils/typedDataConverter.js.map +1 -0
  882. package/dist/utils/urlResolver.cjs +62 -0
  883. package/dist/utils/urlResolver.cjs.map +1 -0
  884. package/dist/utils/urlResolver.d.ts +56 -0
  885. package/dist/utils/urlResolver.js +37 -0
  886. package/dist/utils/urlResolver.js.map +1 -0
  887. package/dist/utils/wallet.cjs +63 -0
  888. package/dist/utils/wallet.cjs.map +1 -0
  889. package/dist/utils/wallet.d.ts +94 -0
  890. package/dist/utils/wallet.js +37 -0
  891. package/dist/utils/wallet.js.map +1 -0
  892. package/dist/utils/withEvents.cjs +44 -0
  893. package/dist/utils/withEvents.cjs.map +1 -0
  894. package/dist/utils/withEvents.d.ts +56 -0
  895. package/dist/utils/withEvents.js +18 -0
  896. package/dist/utils/withEvents.js.map +1 -0
  897. package/package.json +63 -29
  898. package/dist/browser-DY8XDblx.d.ts +0 -241
  899. package/dist/chains.browser.cjs.map +0 -1
  900. package/dist/chains.d.cts +0 -2
  901. package/dist/chains.node.d.cts +0 -2
  902. package/dist/index.d.cts +0 -2
  903. package/dist/node-D9-F9uEP.d.cts +0 -238
  904. package/dist/node-D9-F9uEP.d.ts +0 -238
  905. package/dist/node.d.cts +0 -1
  906. package/dist/platform.d.cts +0 -2
  907. package/dist/platform.node.d.cts +0 -105
@@ -0,0 +1,4339 @@
1
+ import { getAddress } from "viem";
2
+ import { gasAwareMulticall } from "../utils/multicall";
3
+ import { PollingManager } from "../core/pollingManager";
4
+ import {
5
+ RelayerError,
6
+ UserRejectedRequestError,
7
+ SerializationError,
8
+ SignatureError,
9
+ NetworkError,
10
+ NonceError,
11
+ BlockchainError,
12
+ ServerUrlMismatchError,
13
+ PermissionError
14
+ } from "../errors";
15
+ import { getContractAddress } from "../config/addresses";
16
+ import { getAbi } from "../generated/abi";
17
+ import { createGrantFile, getGrantFileHash } from "../utils/grantFiles";
18
+ import { validateGrant } from "../utils/grantValidation";
19
+ import { withSignatureCache } from "../utils/signatureCache";
20
+ import { formatSignatureForContract } from "../utils/signatureFormatter";
21
+ import { toViemTypedDataDefinition } from "../utils/typedDataConverter";
22
+ import { BaseController } from "./base";
23
+ class PermissionsController extends BaseController {
24
+ constructor(context) {
25
+ super(context);
26
+ }
27
+ /**
28
+ * Grants permission for an application to access user data with gasless transactions.
29
+ *
30
+ * This method provides a complete end-to-end permission grant flow that returns
31
+ * the permission ID and other relevant data immediately after successful submission.
32
+ * For advanced users who need more control over the transaction lifecycle, use
33
+ * `submitPermissionGrant()` instead.
34
+ *
35
+ * @param params - The permission grant configuration object
36
+ * @returns Promise resolving to permission data from the PermissionAdded event
37
+ * @throws {RelayerError} When gasless transaction submission fails
38
+ * @throws {SignatureError} When user rejects the signature request
39
+ * @throws {SerializationError} When grant data cannot be serialized
40
+ * @throws {BlockchainError} When permission grant fails or event parsing fails
41
+ * @throws {NetworkError} When transaction confirmation times out
42
+ * @example
43
+ * ```typescript
44
+ * const result = await vana.permissions.grant({
45
+ * grantee: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36",
46
+ * operation: "llm_inference",
47
+ * parameters: {
48
+ * model: "gpt-4",
49
+ * maxTokens: 1000,
50
+ * temperature: 0.7,
51
+ * },
52
+ * });
53
+ *
54
+ * console.log(`Permission ${result.permissionId} granted to ${result.user}`);
55
+ * console.log(`Transaction: ${result.transactionHash}`);
56
+ *
57
+ * // Can immediately use the permission ID for other operations
58
+ * await vana.permissions.revoke({ permissionId: result.permissionId });
59
+ * ```
60
+ */
61
+ async grant(params, options) {
62
+ this.assertWallet();
63
+ const { typedData, signature } = await this.createAndSign(params);
64
+ const result = await this.submitSignedGrantWithEvents(
65
+ typedData,
66
+ signature,
67
+ options
68
+ );
69
+ return result;
70
+ }
71
+ /**
72
+ * Submits a permission grant transaction and returns a handle for flexible result access.
73
+ *
74
+ * @remarks
75
+ * This lower-level method provides maximum control over transaction timing.
76
+ * Returns a TransactionResult that can be serialized and passed across API boundaries.
77
+ * Use this when handling multiple transactions or when you need granular control.
78
+ *
79
+ * @param params - The permission grant configuration object
80
+ * @returns Promise resolving to TransactionResult with hash and event parsing capabilities
81
+ * @throws {RelayerError} When gasless transaction submission fails
82
+ * @throws {SignatureError} When user rejects the signature request
83
+ * @throws {SerializationError} When grant data cannot be serialized
84
+ * @throws {BlockchainError} When permission grant preparation fails
85
+ * @example
86
+ * ```typescript
87
+ * // Submit transaction and get immediate hash access
88
+ * const tx = await vana.permissions.submitPermissionGrant(params);
89
+ * console.log(`Transaction submitted: ${tx.hash}`);
90
+ *
91
+ * // To wait for events, use SDK's waitForTransactionEvents
92
+ * const eventData = await vana.waitForTransactionEvents(tx.hash);
93
+ * console.log(`Permission ID: ${eventData.permissionId}`);
94
+ * ```
95
+ */
96
+ async submitPermissionGrant(params, options) {
97
+ this.assertWallet();
98
+ const { typedData, signature } = await this.createAndSign(params);
99
+ return await this.submitSignedGrant(typedData, signature, options);
100
+ }
101
+ /**
102
+ * Prepares a permission grant with preview before signing.
103
+ *
104
+ * @remarks
105
+ * This method implements a two-phase commit workflow that allows applications
106
+ * to show users a preview of what they're authorizing before requesting a signature.
107
+ * Unlike `createAndSign()`, this method does NOT upload to IPFS or prompt for signatures
108
+ * until the returned `confirm()` function is called.
109
+ * @param params - The permission grant parameters
110
+ * @returns A promise resolving to a preview object and confirm function
111
+ * @throws {SerializationError} When grant parameters are invalid or cannot be serialized
112
+ * @throws {BlockchainError} When grant validation fails or preparation encounters an error
113
+ * @example
114
+ * ```typescript
115
+ * const { preview, confirm } = await vana.permissions.prepareGrant({
116
+ * grantee: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36",
117
+ * operation: "llm_inference",
118
+ * files: [1, 2, 3],
119
+ * parameters: { model: "gpt-4", prompt: "Analyze my social media data" }
120
+ * });
121
+ *
122
+ * console.log(`Granting ${preview.operation} access to ${preview.files?.length} files`);
123
+ * const transactionHash = await confirm();
124
+ * ```
125
+ */
126
+ async prepareGrant(params, options) {
127
+ this.assertWallet();
128
+ try {
129
+ const grantFile = createGrantFile(params);
130
+ validateGrant(grantFile);
131
+ return {
132
+ preview: grantFile,
133
+ confirm: async () => {
134
+ return await this.confirmGrantInternalWithEvents(
135
+ params,
136
+ grantFile,
137
+ options
138
+ );
139
+ }
140
+ };
141
+ } catch (error) {
142
+ if (error instanceof Error) {
143
+ if (error instanceof RelayerError || error instanceof UserRejectedRequestError || error instanceof SerializationError || error instanceof SignatureError || error instanceof NetworkError || error instanceof NonceError) {
144
+ throw error;
145
+ }
146
+ throw new BlockchainError(
147
+ `Permission grant preparation failed: ${error.message}`,
148
+ error
149
+ );
150
+ }
151
+ throw new BlockchainError(
152
+ "Permission grant preparation failed with unknown error"
153
+ );
154
+ }
155
+ }
156
+ /**
157
+ * Completes the grant process after user confirmation.
158
+ *
159
+ * @remarks
160
+ * This internal method is called by the confirm() function returned from prepareGrant().
161
+ * It handles IPFS upload, signature creation, and transaction submission.
162
+ *
163
+ * @param params - The permission grant parameters containing user and operation details
164
+ * @param grantFile - The prepared grant file with permissions and metadata
165
+ * @returns Promise resolving to TransactionResult for flexible result access
166
+ * @throws {BlockchainError} When permission grant confirmation fails
167
+ * @throws {NetworkError} When IPFS upload fails
168
+ * @throws {SignatureError} When user rejects the signature
169
+ */
170
+ async confirmGrantInternal(params, grantFile, options) {
171
+ try {
172
+ let { grantUrl } = params;
173
+ console.debug("\u{1F50D} Debug - Grant URL from params:", grantUrl);
174
+ if (!grantUrl) {
175
+ const canStoreViaRelayer = this.context.relayer !== void 0;
176
+ if (!canStoreViaRelayer && !this.context.storageManager) {
177
+ if (this.context.validateStorageRequired) {
178
+ this.context.validateStorageRequired();
179
+ } else {
180
+ throw new Error(
181
+ "No storage available. Provide a grantUrl, configure relayer, or storageManager."
182
+ );
183
+ }
184
+ }
185
+ if (canStoreViaRelayer && this.context.relayer) {
186
+ const request = {
187
+ type: "direct",
188
+ operation: "storeGrantFile",
189
+ params: grantFile
190
+ };
191
+ const response = await this.context.relayer(request);
192
+ if (response.type === "error") {
193
+ throw new Error(response.error);
194
+ }
195
+ if (response.type === "direct" && typeof response.result === "object" && response.result !== null && "url" in response.result) {
196
+ grantUrl = response.result.url;
197
+ } else {
198
+ throw new Error("Invalid response from relayer for grant storage");
199
+ }
200
+ } else if (this.context.storageManager) {
201
+ const blob = new Blob([JSON.stringify(grantFile)], {
202
+ type: "application/json"
203
+ });
204
+ const result = await this.context.storageManager.upload(
205
+ blob,
206
+ `grant-${Date.now()}.json`
207
+ );
208
+ grantUrl = result.url;
209
+ }
210
+ if (!grantUrl) {
211
+ throw new Error("Failed to store grant file - no URL returned");
212
+ }
213
+ }
214
+ const nonce = await this.getPermissionsUserNonce();
215
+ console.debug(
216
+ "\u{1F50D} Debug - Final grant URL being passed to compose:",
217
+ grantUrl
218
+ );
219
+ const typedData = await this.composePermissionGrantMessage({
220
+ grantee: params.grantee,
221
+ operation: params.operation,
222
+ // Placeholder - real data is in IPFS
223
+ files: params.files,
224
+ // Placeholder - real data is in IPFS
225
+ grantUrl,
226
+ serializedParameters: getGrantFileHash(grantFile),
227
+ // Hash as placeholder
228
+ nonce
229
+ });
230
+ const signature = await this.signTypedData(typedData);
231
+ return await this.submitSignedGrant(typedData, signature, options);
232
+ } catch (error) {
233
+ if (error instanceof Error) {
234
+ if (error instanceof RelayerError || error instanceof UserRejectedRequestError || error instanceof SerializationError || error instanceof SignatureError || error instanceof NetworkError || error instanceof NonceError) {
235
+ throw error;
236
+ }
237
+ throw new BlockchainError(
238
+ `Permission grant confirmation failed: ${error.message}`,
239
+ error
240
+ );
241
+ }
242
+ throw new BlockchainError(
243
+ "Permission grant confirmation failed with unknown error"
244
+ );
245
+ }
246
+ }
247
+ /**
248
+ * Creates typed data and signature for a permission grant without submitting.
249
+ *
250
+ * @remarks
251
+ * This method handles the first phase of permission granting: creating the grant file,
252
+ * storing it on IPFS, and generating the user's EIP-712 signature. Use this when you
253
+ * want to handle submission separately or batch multiple operations. The method validates
254
+ * the grant file against the JSON schema before creating the signature.
255
+ *
256
+ * For interactive user flows, consider using `prepareGrant()` instead,
257
+ * which allows showing a preview before signing.
258
+ * @param params - The permission grant configuration object
259
+ * @returns A promise resolving to the typed data structure and signature for gasless submission
260
+ * @throws {SignatureError} When the user rejects the signature request
261
+ * @throws {SerializationError} When grant data cannot be properly formatted
262
+ * @throws {BlockchainError} When permission grant preparation fails
263
+ * @throws {NetworkError} When storage operations fail
264
+ * @example
265
+ * ```typescript
266
+ * const { typedData, signature } = await vana.permissions.createAndSign({
267
+ * grantee: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36",
268
+ * operation: "data_analysis",
269
+ * parameters: { analysisType: "sentiment" },
270
+ * });
271
+ *
272
+ * const transactionHash = await vana.permissions.submitSignedGrant(typedData, signature);
273
+ * ```
274
+ */
275
+ async createAndSign(params) {
276
+ this.assertWallet();
277
+ try {
278
+ const grantFile = createGrantFile(params);
279
+ validateGrant(grantFile);
280
+ let { grantUrl } = params;
281
+ console.debug("\u{1F50D} Debug - Grant URL from params:", grantUrl);
282
+ if (!grantUrl) {
283
+ const canStoreViaRelayer = this.context.relayer !== void 0;
284
+ if (!canStoreViaRelayer && !this.context.storageManager) {
285
+ if (this.context.validateStorageRequired) {
286
+ this.context.validateStorageRequired();
287
+ } else {
288
+ throw new Error(
289
+ "No storage available. Provide a grantUrl, configure relayer, or storageManager."
290
+ );
291
+ }
292
+ }
293
+ if (canStoreViaRelayer && this.context.relayer) {
294
+ const request = {
295
+ type: "direct",
296
+ operation: "storeGrantFile",
297
+ params: grantFile
298
+ };
299
+ const response = await this.context.relayer(request);
300
+ if (response.type === "error") {
301
+ throw new Error(response.error);
302
+ }
303
+ if (response.type === "direct" && typeof response.result === "object" && response.result !== null && "url" in response.result) {
304
+ grantUrl = response.result.url;
305
+ } else {
306
+ throw new Error("Invalid response from relayer for grant storage");
307
+ }
308
+ } else if (this.context.storageManager) {
309
+ const blob = new Blob([JSON.stringify(grantFile)], {
310
+ type: "application/json"
311
+ });
312
+ const result = await this.context.storageManager.upload(
313
+ blob,
314
+ `grant-${Date.now()}.json`
315
+ );
316
+ grantUrl = result.url;
317
+ }
318
+ if (!grantUrl) {
319
+ throw new Error("Failed to store grant file - no URL returned");
320
+ }
321
+ }
322
+ const nonce = await this.getPermissionsUserNonce();
323
+ console.debug(
324
+ "\u{1F50D} Debug - Final grant URL being passed to compose:",
325
+ grantUrl
326
+ );
327
+ const typedData = await this.composePermissionGrantMessage({
328
+ grantee: params.grantee,
329
+ operation: params.operation,
330
+ // Placeholder - real data is in IPFS
331
+ files: params.files,
332
+ // Placeholder - real data is in IPFS
333
+ grantUrl,
334
+ serializedParameters: getGrantFileHash(grantFile),
335
+ // Hash as placeholder
336
+ nonce
337
+ });
338
+ const signature = await this.signTypedData(typedData);
339
+ return { typedData, signature };
340
+ } catch (error) {
341
+ if (error instanceof Error) {
342
+ if (error instanceof RelayerError || error instanceof UserRejectedRequestError || error instanceof SerializationError || error instanceof SignatureError || error instanceof NetworkError || error instanceof NonceError) {
343
+ throw error;
344
+ }
345
+ throw new BlockchainError(
346
+ `Permission grant preparation failed: ${error.message}`,
347
+ error
348
+ );
349
+ }
350
+ throw new BlockchainError(
351
+ "Permission grant preparation failed with unknown error"
352
+ );
353
+ }
354
+ }
355
+ /**
356
+ * Submits an already-signed permission grant to the blockchain.
357
+ *
358
+ * @remarks
359
+ * This method supports both relayer-based gasless transactions and direct transactions.
360
+ * It automatically converts `bigint` values to JSON-safe strings when using relayer
361
+ * callbacks and handles transaction submission with proper error handling and retry logic.
362
+ * @param typedData - The EIP-712 typed data structure for the permission grant
363
+ * @param signature - The user's signature as a hex string
364
+ * @returns A Promise that resolves to the transaction hash
365
+ * @throws {RelayerError} When gasless transaction submission fails
366
+ * @throws {BlockchainError} When permission submission fails
367
+ * @throws {NetworkError} When network communication fails
368
+ * @example
369
+ * ```typescript
370
+ * const txHash = await vana.permissions.submitSignedGrant(
371
+ * typedData,
372
+ * "0x1234..."
373
+ * );
374
+ * ```
375
+ */
376
+ async submitSignedGrant(typedData, signature, options) {
377
+ try {
378
+ console.debug(
379
+ "\u{1F50D} Debug - submitSignedGrant called with typed data:",
380
+ JSON.stringify(
381
+ typedData,
382
+ (_key, value) => typeof value === "bigint" ? value.toString() : value,
383
+ 2
384
+ )
385
+ );
386
+ if (this.context.relayer) {
387
+ const response = await this.context.relayer({
388
+ type: "signed",
389
+ operation: "submitAddPermission",
390
+ typedData,
391
+ signature,
392
+ expectedUserAddress: this.context.userAddress
393
+ });
394
+ if (response.type === "error") {
395
+ throw new Error(`Relayer error: ${response.error}`);
396
+ }
397
+ let finalHash;
398
+ if (response.type === "submitted") {
399
+ finalHash = response.hash;
400
+ } else if (response.type === "pending") {
401
+ const pollResult = await this.pollRelayerForConfirmation(
402
+ response.operationId,
403
+ options
404
+ );
405
+ finalHash = pollResult.hash;
406
+ } else if (response.type === "confirmed") {
407
+ finalHash = response.hash;
408
+ } else if (response.type === "signed") {
409
+ finalHash = response.hash;
410
+ } else {
411
+ throw new Error(
412
+ "Invalid response from relayer: unexpected response type"
413
+ );
414
+ }
415
+ const account = this.context.walletClient?.account ?? this.context.userAddress;
416
+ const { tx } = await import("../utils/transactionHelpers");
417
+ return tx({
418
+ hash: finalHash,
419
+ from: typeof account === "string" ? account : account.address,
420
+ contract: "DataPortabilityPermissions",
421
+ fn: "addPermission"
422
+ });
423
+ } else {
424
+ return await this.submitDirectTransaction(
425
+ typedData,
426
+ signature,
427
+ options
428
+ );
429
+ }
430
+ } catch (error) {
431
+ if (error instanceof RelayerError || error instanceof NetworkError || error instanceof UserRejectedRequestError || error instanceof SignatureError || error instanceof NonceError) {
432
+ throw error;
433
+ }
434
+ throw new BlockchainError(
435
+ `Permission submission failed: ${error instanceof Error ? error.message : "Unknown error"}`,
436
+ error
437
+ );
438
+ }
439
+ }
440
+ /**
441
+ * Submits an already-signed trust server transaction to the blockchain.
442
+ *
443
+ * @remarks
444
+ * This method extracts the trust server input from typed data and submits it directly.
445
+ * Used internally by trust server methods after signature collection.
446
+ *
447
+ * @param typedData - The EIP-712 typed data for TrustServer
448
+ * @param signature - The user's signature obtained via `signTypedData()`
449
+ * @returns Promise resolving to TransactionResult for transaction tracking
450
+ * @throws {BlockchainError} When contract submission fails
451
+ * @throws {NetworkError} When blockchain communication fails
452
+ * @example
453
+ * ```typescript
454
+ * const txHandle = await vana.permissions.submitSignedTrustServer(
455
+ * typedData,
456
+ * "0x1234..."
457
+ * );
458
+ * const result = await txHandle.waitForEvents();
459
+ * ```
460
+ */
461
+ async submitSignedTrustServer(typedData, signature, options) {
462
+ try {
463
+ const trustServerInput = {
464
+ nonce: BigInt(typedData.message.nonce),
465
+ serverId: typedData.message.serverId
466
+ };
467
+ const hash = await this.submitTrustServerTransaction(
468
+ trustServerInput,
469
+ signature,
470
+ options
471
+ );
472
+ const account = this.context.userAddress;
473
+ const { tx } = await import("../utils/transactionHelpers");
474
+ return tx({
475
+ hash,
476
+ from: account,
477
+ contract: "DataPortabilityServers",
478
+ fn: "trustServerWithSignature"
479
+ });
480
+ } catch (error) {
481
+ if (error instanceof RelayerError || error instanceof NetworkError || error instanceof UserRejectedRequestError || error instanceof SignatureError || error instanceof NonceError) {
482
+ throw error;
483
+ }
484
+ if (error instanceof Error && error.message.includes("ServerUrlMismatch")) {
485
+ const match = error.message.match(
486
+ /ServerUrlMismatch\(string existingUrl, string providedUrl\)\s+\(([^,]+),\s*([^)]+)\)/
487
+ );
488
+ if (match) {
489
+ const existingUrl = match[1].trim();
490
+ const providedUrl = match[2].trim();
491
+ throw new ServerUrlMismatchError(
492
+ existingUrl,
493
+ providedUrl,
494
+ typedData.message.serverId.toString()
495
+ );
496
+ }
497
+ }
498
+ throw new BlockchainError(
499
+ `Trust server submission failed: ${error instanceof Error ? error.message : "Unknown error"}`,
500
+ error
501
+ );
502
+ }
503
+ }
504
+ /**
505
+ * Submits an already-signed add and trust server transaction to the blockchain.
506
+ *
507
+ * @remarks
508
+ * This method extracts the add and trust server input from typed data and submits it directly.
509
+ * Combines server registration and trust operations in a single transaction.
510
+ *
511
+ * @param typedData - The EIP-712 typed data for AddAndTrustServer
512
+ * @param signature - The user's signature obtained via `signTypedData()`
513
+ * @returns Promise resolving to TransactionResult for transaction tracking
514
+ * @throws {BlockchainError} When contract submission fails
515
+ * @throws {NetworkError} When blockchain communication fails
516
+ * @example
517
+ * ```typescript
518
+ * const txHandle = await vana.permissions.submitSignedAddAndTrustServer(
519
+ * typedData,
520
+ * "0x1234..."
521
+ * );
522
+ * const result = await txHandle.waitForEvents();
523
+ * ```
524
+ */
525
+ async submitSignedAddAndTrustServer(typedData, signature, options) {
526
+ try {
527
+ const addAndTrustServerInput = {
528
+ nonce: BigInt(typedData.message.nonce),
529
+ serverAddress: typedData.message.serverAddress,
530
+ serverUrl: typedData.message.serverUrl,
531
+ publicKey: typedData.message.publicKey
532
+ };
533
+ const hash = await this.submitAddAndTrustServerTransaction(
534
+ addAndTrustServerInput,
535
+ signature,
536
+ options
537
+ );
538
+ const account = this.context.walletClient?.account ?? this.context.userAddress;
539
+ const { tx } = await import("../utils/transactionHelpers");
540
+ return tx({
541
+ hash,
542
+ from: typeof account === "string" ? account : account.address,
543
+ contract: "DataPortabilityServers",
544
+ fn: "addAndTrustServerWithSignature"
545
+ });
546
+ } catch (error) {
547
+ if (error instanceof RelayerError || error instanceof NetworkError || error instanceof UserRejectedRequestError || error instanceof SignatureError || error instanceof NonceError) {
548
+ throw error;
549
+ }
550
+ throw new BlockchainError(
551
+ `Add and trust server submission failed444444: ${error instanceof Error ? error.message : "Unknown error"}`,
552
+ error
553
+ );
554
+ }
555
+ }
556
+ /**
557
+ * Internal method to submit a signed grant and wait for events.
558
+ *
559
+ * @internal
560
+ * @param typedData - The EIP-712 typed data for the permission grant
561
+ * @param signature - The user's signature authorizing the transaction
562
+ * @returns Promise resolving to PermissionGrantResult with parsed events
563
+ */
564
+ async submitSignedGrantWithEvents(typedData, signature, options) {
565
+ const txResult = await this.submitSignedGrant(
566
+ typedData,
567
+ signature,
568
+ options
569
+ );
570
+ if (!this.context.waitForTransactionEvents) {
571
+ throw new BlockchainError("waitForTransactionEvents not configured");
572
+ }
573
+ const result = await this.context.waitForTransactionEvents(txResult);
574
+ const event = result.expectedEvents.PermissionAdded;
575
+ if (!event) {
576
+ throw new BlockchainError(
577
+ "PermissionAdded event not found in transaction"
578
+ );
579
+ }
580
+ const receipt = await this.context.publicClient.getTransactionReceipt({
581
+ hash: result.hash
582
+ });
583
+ return {
584
+ transactionHash: result.hash,
585
+ blockNumber: receipt.blockNumber,
586
+ gasUsed: receipt.gasUsed,
587
+ permissionId: event.permissionId,
588
+ user: event.user,
589
+ grant: event.grant,
590
+ fileIds: event.fileIds
591
+ };
592
+ }
593
+ /**
594
+ * Internal method for confirm grant with events.
595
+ *
596
+ * @internal
597
+ * @param params - The permission grant parameters
598
+ * @param grantFile - The pre-created grant file object
599
+ * @returns Promise resolving to PermissionGrantResult with parsed events
600
+ */
601
+ async confirmGrantInternalWithEvents(params, grantFile, options) {
602
+ const txResult = await this.confirmGrantInternal(
603
+ params,
604
+ grantFile,
605
+ options
606
+ );
607
+ if (!this.context.waitForTransactionEvents) {
608
+ throw new BlockchainError("waitForTransactionEvents not configured");
609
+ }
610
+ const result = await this.context.waitForTransactionEvents(txResult);
611
+ const event = result.expectedEvents.PermissionAdded;
612
+ if (!event) {
613
+ throw new BlockchainError(
614
+ "PermissionAdded event not found in transaction"
615
+ );
616
+ }
617
+ const receipt = await this.context.publicClient.getTransactionReceipt({
618
+ hash: result.hash
619
+ });
620
+ return {
621
+ transactionHash: result.hash,
622
+ blockNumber: receipt.blockNumber,
623
+ gasUsed: receipt.gasUsed,
624
+ permissionId: event.permissionId,
625
+ user: event.user,
626
+ grant: event.grant,
627
+ fileIds: event.fileIds
628
+ };
629
+ }
630
+ /**
631
+ * Polls the relayer for confirmation of a pending operation.
632
+ *
633
+ * @param operationId - The operation ID to poll
634
+ * @param options - Polling configuration including status updates and cancellation
635
+ * @returns Promise resolving to the confirmed hash and receipt
636
+ * @throws {TransactionPendingError} When the operation times out
637
+ * @throws {Error} When the operation fails or is cancelled
638
+ * @internal
639
+ */
640
+ async pollRelayerForConfirmation(operationId, options) {
641
+ if (!this.context.relayer) {
642
+ throw new Error("Relayer not configured for polling");
643
+ }
644
+ const pollingManager = new PollingManager(this.context.relayer);
645
+ return await pollingManager.startPolling(operationId, {
646
+ signal: options?.signal,
647
+ onStatusUpdate: options?.onStatusUpdate,
648
+ ...options?.pollingOptions
649
+ });
650
+ }
651
+ /**
652
+ * Submits an already-signed permission revoke transaction to the blockchain.
653
+ *
654
+ * @remarks
655
+ * This method handles the revocation of previously granted permissions.
656
+ * Used internally by revocation methods after signature collection.
657
+ *
658
+ * @param typedData - The EIP-712 typed data for PermissionRevoke
659
+ * @param signature - The user's signature obtained via `signTypedData()`
660
+ * @returns Promise resolving to TransactionResult for transaction tracking
661
+ * @throws {BlockchainError} When contract submission fails
662
+ * @throws {NetworkError} When blockchain communication fails
663
+ * @example
664
+ * ```typescript
665
+ * const txHandle = await vana.permissions.submitSignedRevoke(
666
+ * typedData,
667
+ * "0x1234..."
668
+ * );
669
+ * const result = await txHandle.waitForEvents();
670
+ * ```
671
+ */
672
+ async submitSignedRevoke(typedData, signature, options) {
673
+ try {
674
+ let hash;
675
+ if (this.context.relayer) {
676
+ const response = await this.context.relayer({
677
+ type: "signed",
678
+ operation: "submitPermissionRevoke",
679
+ typedData,
680
+ signature,
681
+ expectedUserAddress: this.context.userAddress
682
+ });
683
+ if (response.type === "error") {
684
+ throw new Error(`Relayer error: ${response.error}`);
685
+ }
686
+ if (response.type === "submitted") {
687
+ hash = response.hash;
688
+ } else if (response.type === "pending") {
689
+ const pollResult = await this.pollRelayerForConfirmation(
690
+ response.operationId,
691
+ options
692
+ );
693
+ hash = pollResult.hash;
694
+ } else if (response.type === "confirmed") {
695
+ hash = response.hash;
696
+ } else if (response.type === "signed") {
697
+ hash = response.hash;
698
+ } else {
699
+ throw new Error(
700
+ "Invalid response from relayer: unexpected response type"
701
+ );
702
+ }
703
+ } else {
704
+ hash = await this.submitDirectRevokeTransaction(
705
+ typedData,
706
+ signature,
707
+ options
708
+ );
709
+ }
710
+ const account = this.context.walletClient?.account ?? this.context.userAddress;
711
+ const { tx } = await import("../utils/transactionHelpers");
712
+ return tx({
713
+ hash,
714
+ from: typeof account === "string" ? account : account.address,
715
+ contract: "DataPortabilityPermissions",
716
+ fn: "revokePermissionWithSignature"
717
+ });
718
+ } catch (error) {
719
+ if (error instanceof RelayerError || error instanceof NetworkError || error instanceof UserRejectedRequestError || error instanceof SignatureError || error instanceof NonceError) {
720
+ throw error;
721
+ }
722
+ throw new BlockchainError(
723
+ `Permission revoke submission failed: ${error instanceof Error ? error.message : "Unknown error"}`,
724
+ error
725
+ );
726
+ }
727
+ }
728
+ /**
729
+ * Submits an already-signed untrust server transaction to the blockchain.
730
+ *
731
+ * @remarks
732
+ * This method handles the removal of trusted servers.
733
+ * Used internally by untrust server methods after signature collection.
734
+ *
735
+ * @param typedData - The EIP-712 typed data for UntrustServer
736
+ * @param signature - The user's signature obtained via `signTypedData()`
737
+ * @returns Promise resolving to TransactionResult for transaction tracking
738
+ * @throws {BlockchainError} When contract submission fails
739
+ * @throws {NetworkError} When blockchain communication fails
740
+ * @example
741
+ * ```typescript
742
+ * const txHandle = await vana.permissions.submitSignedUntrustServer(
743
+ * typedData,
744
+ * "0x1234..."
745
+ * );
746
+ * const result = await txHandle.waitForEvents();
747
+ * ```
748
+ */
749
+ async submitSignedUntrustServer(typedData, signature, options) {
750
+ try {
751
+ let hash;
752
+ if (this.context.relayer) {
753
+ const response = await this.context.relayer({
754
+ type: "signed",
755
+ operation: "submitUntrustServer",
756
+ typedData,
757
+ signature,
758
+ expectedUserAddress: this.context.userAddress
759
+ });
760
+ if (response.type === "submitted") {
761
+ hash = response.hash;
762
+ } else if (response.type === "signed") {
763
+ hash = response.hash;
764
+ } else if (response.type === "error") {
765
+ throw new Error(`Relayer error: ${response.error}`);
766
+ } else {
767
+ throw new Error(
768
+ "Invalid response from relayer: expected signed transaction"
769
+ );
770
+ }
771
+ } else {
772
+ hash = await this.submitSignedUntrustTransaction(
773
+ typedData,
774
+ signature,
775
+ options
776
+ );
777
+ }
778
+ const account = this.context.walletClient?.account ?? this.context.userAddress;
779
+ const { tx } = await import("../utils/transactionHelpers");
780
+ return tx({
781
+ hash,
782
+ from: typeof account === "string" ? account : account.address,
783
+ contract: "DataPortabilityServers",
784
+ fn: "untrustServerWithSignature"
785
+ });
786
+ } catch (error) {
787
+ if (error instanceof RelayerError || error instanceof NetworkError || error instanceof UserRejectedRequestError || error instanceof SignatureError || error instanceof NonceError) {
788
+ throw error;
789
+ }
790
+ throw new BlockchainError(
791
+ `Untrust server submission failed: ${error instanceof Error ? error.message : "Unknown error"}`,
792
+ error
793
+ );
794
+ }
795
+ }
796
+ /**
797
+ * Submits a signed transaction directly to the blockchain.
798
+ *
799
+ * @remarks
800
+ * Internal method used when relayer callbacks are not available. Formats the signature
801
+ * and submits the permission grant directly to the smart contract.
802
+ *
803
+ * @param typedData - The typed data structure for the permission grant
804
+ * @param signature - The cryptographic signature authorizing the transaction
805
+ * @returns Promise resolving to the transaction hash
806
+ * @throws {BlockchainError} When contract submission fails
807
+ */
808
+ async submitDirectTransaction(typedData, signature, options) {
809
+ this.assertWallet();
810
+ const chainId = await this.context.publicClient.getChainId();
811
+ const DataPortabilityPermissionsAddress = getContractAddress(
812
+ chainId,
813
+ "DataPortabilityPermissions"
814
+ );
815
+ const DataPortabilityPermissionsAbi = getAbi("DataPortabilityPermissions");
816
+ const permissionInput = {
817
+ nonce: typedData.message.nonce,
818
+ granteeId: typedData.message.granteeId,
819
+ grant: typedData.message.grant,
820
+ fileIds: typedData.message.fileIds
821
+ };
822
+ console.debug("\u{1F50D} Debug - Permission input being sent to contract:", {
823
+ nonce: permissionInput.nonce.toString(),
824
+ grant: permissionInput.grant,
825
+ fileIds: permissionInput.fileIds.map((id) => id.toString())
826
+ });
827
+ console.debug("\u{1F50D} Debug - Grant field value:", typedData.message.grant);
828
+ console.debug(
829
+ "\u{1F50D} Debug - Grant field length:",
830
+ typedData.message.grant?.length ?? 0
831
+ );
832
+ const formattedSignature = formatSignatureForContract(signature);
833
+ const account = this.context.walletClient?.account ?? this.context.userAddress;
834
+ const txHash = await this.context.walletClient.writeContract({
835
+ address: DataPortabilityPermissionsAddress,
836
+ abi: DataPortabilityPermissionsAbi,
837
+ functionName: "addPermission",
838
+ args: [permissionInput, formattedSignature],
839
+ account,
840
+ chain: this.context.walletClient?.chain ?? null,
841
+ ...this.spreadTransactionOptions(options)
842
+ });
843
+ const { tx } = await import("../utils/transactionHelpers");
844
+ return tx({
845
+ hash: txHash,
846
+ from: typeof account === "string" ? account : account.address,
847
+ contract: "DataPortabilityPermissions",
848
+ fn: "addPermission"
849
+ });
850
+ }
851
+ /**
852
+ * Revokes a previously granted permission.
853
+ *
854
+ * This method provides complete revocation with automatic event parsing to confirm
855
+ * the permission was successfully revoked. For advanced users who need more control,
856
+ * use `submitPermissionRevoke()` instead.
857
+ *
858
+ * @param params - Parameters for revoking the permission
859
+ * @param params.permissionId - Permission identifier (accepts bigint, number, or string).
860
+ * Obtain from permission grants via `getUserPermissionGrantsOnChain()`.
861
+ * @returns Promise resolving to revocation data from PermissionRevoked event
862
+ * @throws {BlockchainError} When revocation fails or event parsing fails
863
+ * @throws {UserRejectedRequestError} When user rejects the transaction
864
+ * @throws {NetworkError} When transaction confirmation times out
865
+ * @example
866
+ * ```typescript
867
+ * // Revoke a permission and get confirmation
868
+ * const result = await vana.permissions.revoke({
869
+ * permissionId: 123n
870
+ * });
871
+ * console.log(`Permission ${result.permissionId} revoked in transaction ${result.transactionHash}`);
872
+ * console.log(`Revoked in block ${result.blockNumber}`);
873
+ * ```
874
+ */
875
+ async revoke(params) {
876
+ this.assertWallet();
877
+ const txResult = await this.submitPermissionRevoke(params);
878
+ if (!this.context.waitForTransactionEvents) {
879
+ throw new BlockchainError("waitForTransactionEvents not configured");
880
+ }
881
+ const result = await this.context.waitForTransactionEvents(txResult);
882
+ const event = result.expectedEvents.PermissionRevoked;
883
+ if (!event) {
884
+ throw new BlockchainError(
885
+ "PermissionRevoked event not found in transaction"
886
+ );
887
+ }
888
+ const receipt = await this.context.publicClient.getTransactionReceipt({
889
+ hash: result.hash
890
+ });
891
+ return {
892
+ transactionHash: result.hash,
893
+ blockNumber: receipt.blockNumber,
894
+ gasUsed: receipt.gasUsed,
895
+ permissionId: event.permissionId
896
+ };
897
+ }
898
+ /**
899
+ * Submits a permission revocation transaction and returns the transaction hash immediately.
900
+ *
901
+ * This is the lower-level method that provides maximum control over transaction timing.
902
+ * Use this when you want to handle transaction confirmation and event parsing separately.
903
+ *
904
+ * @param params - Parameters for revoking the permission
905
+ * @param options - Optional transaction options for gas parameters and timeout
906
+ * @returns Promise resolving to the transaction hash when successfully submitted
907
+ * @throws {BlockchainError} When revocation transaction fails
908
+ * @throws {UserRejectedRequestError} When user rejects the transaction
909
+ * @example
910
+ * ```typescript
911
+ * // Submit revocation and handle confirmation later
912
+ * const txHash = await vana.permissions.submitPermissionRevoke({
913
+ * permissionId: 123n
914
+ * });
915
+ * console.log(`Revocation submitted: ${txHash}`);
916
+ * ```
917
+ */
918
+ async submitPermissionRevoke(params, options) {
919
+ this.assertWallet();
920
+ try {
921
+ if (!this.context.walletClient?.chain?.id) {
922
+ throw new BlockchainError("Chain ID not available");
923
+ }
924
+ const chainId = await this.context.publicClient.getChainId();
925
+ const DataPortabilityPermissionsAddress = getContractAddress(
926
+ chainId,
927
+ "DataPortabilityPermissions"
928
+ );
929
+ const DataPortabilityPermissionsAbi = getAbi(
930
+ "DataPortabilityPermissions"
931
+ );
932
+ const account = this.context.walletClient?.account ?? this.context.userAddress;
933
+ const txHash = await this.context.walletClient.writeContract({
934
+ address: DataPortabilityPermissionsAddress,
935
+ abi: DataPortabilityPermissionsAbi,
936
+ functionName: "revokePermission",
937
+ args: [params.permissionId],
938
+ account,
939
+ chain: this.context.walletClient?.chain ?? null,
940
+ ...options?.gas && { gas: options.gas },
941
+ ...options?.nonce && { nonce: options.nonce },
942
+ // Use EIP-1559 if available, otherwise fall back to legacy gasPrice
943
+ ...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
944
+ ...options.maxFeePerGas && {
945
+ maxFeePerGas: options.maxFeePerGas
946
+ },
947
+ ...options.maxPriorityFeePerGas && {
948
+ maxPriorityFeePerGas: options.maxPriorityFeePerGas
949
+ }
950
+ } : options?.gasPrice && { gasPrice: options.gasPrice }
951
+ });
952
+ const { tx } = await import("../utils/transactionHelpers");
953
+ return tx({
954
+ hash: txHash,
955
+ from: typeof account === "string" ? account : account.address,
956
+ contract: "DataPortabilityPermissions",
957
+ fn: "revokePermission"
958
+ });
959
+ } catch (error) {
960
+ if (error instanceof Error) {
961
+ if (error instanceof RelayerError || error instanceof UserRejectedRequestError || error instanceof SerializationError || error instanceof SignatureError || error instanceof NetworkError || error instanceof NonceError) {
962
+ throw error;
963
+ }
964
+ throw new BlockchainError(
965
+ `Permission revoke failed: ${error.message}`,
966
+ error
967
+ );
968
+ }
969
+ throw new BlockchainError("Permission revoke failed with unknown error");
970
+ }
971
+ }
972
+ /**
973
+ * Revokes a permission with a signature for gasless transactions.
974
+ *
975
+ * @remarks
976
+ * This method creates an EIP-712 signature for permission revocation and submits
977
+ * it either through relayer callbacks or directly to the blockchain. Provides
978
+ * gasless revocation when relayer is configured.
979
+ *
980
+ * @param params - Parameters for revoking the permission
981
+ * @param params.permissionId - Permission identifier to revoke (accepts bigint, number, or string)
982
+ * @returns Promise resolving to TransactionResult for transaction tracking
983
+ * @throws {BlockchainError} When chain ID is not available
984
+ * @throws {NonceError} When retrieving user nonce fails
985
+ * @throws {SignatureError} When user rejects the signature request
986
+ * @throws {RelayerError} When gasless submission fails
987
+ * @throws {PermissionError} When revocation fails for any other reason
988
+ * @example
989
+ * ```typescript
990
+ * const txHandle = await vana.permissions.submitRevokeWithSignature({
991
+ * permissionId: 123n
992
+ * });
993
+ * const result = await txHandle.waitForEvents();
994
+ * console.log(`Permission ${result.permissionId} revoked`);
995
+ * ```
996
+ */
997
+ async submitRevokeWithSignature(params, options) {
998
+ this.assertWallet();
999
+ try {
1000
+ if (!this.context.walletClient?.chain?.id) {
1001
+ throw new BlockchainError("Chain ID not available");
1002
+ }
1003
+ const nonce = await this.getPermissionsUserNonce();
1004
+ const revokePermissionInput = {
1005
+ nonce,
1006
+ permissionId: params.permissionId
1007
+ };
1008
+ const typedData = {
1009
+ domain: await this.getPermissionDomain(),
1010
+ types: {
1011
+ RevokePermission: [
1012
+ { name: "nonce", type: "uint256" },
1013
+ { name: "permissionId", type: "uint256" }
1014
+ ]
1015
+ },
1016
+ primaryType: "RevokePermission",
1017
+ message: revokePermissionInput
1018
+ };
1019
+ const signature = await this.signTypedData(typedData);
1020
+ let hash;
1021
+ if (this.context.relayer) {
1022
+ const response = await this.context.relayer({
1023
+ type: "signed",
1024
+ operation: "submitPermissionRevoke",
1025
+ typedData,
1026
+ signature,
1027
+ expectedUserAddress: this.context.userAddress
1028
+ });
1029
+ if (response.type === "submitted") {
1030
+ hash = response.hash;
1031
+ } else if (response.type === "signed") {
1032
+ hash = response.hash;
1033
+ } else if (response.type === "error") {
1034
+ throw new Error(`Relayer error: ${response.error}`);
1035
+ } else {
1036
+ throw new Error(
1037
+ "Invalid response from relayer: expected signed transaction"
1038
+ );
1039
+ }
1040
+ } else {
1041
+ hash = await this.submitDirectRevokeTransaction(
1042
+ typedData,
1043
+ signature,
1044
+ options
1045
+ );
1046
+ }
1047
+ const account = this.context.walletClient?.account ?? this.context.userAddress;
1048
+ const { tx } = await import("../utils/transactionHelpers");
1049
+ return tx({
1050
+ hash,
1051
+ from: typeof account === "string" ? account : account.address,
1052
+ contract: "DataPortabilityPermissions",
1053
+ fn: "revokePermissionWithSignature"
1054
+ });
1055
+ } catch (error) {
1056
+ throw new PermissionError(
1057
+ `Failed to revoke permission with signature: ${error instanceof Error ? error.message : "Unknown error"}`,
1058
+ error
1059
+ );
1060
+ }
1061
+ }
1062
+ /**
1063
+ * Retrieves the user's current nonce from the DataPortabilityServers contract.
1064
+ * This nonce is used for server-related operations (AddAndTrustServer, TrustServer, UntrustServer).
1065
+ *
1066
+ * @returns Promise resolving to the current servers nonce
1067
+ * @throws {NonceError} When reading nonce from contract fails
1068
+ * @private
1069
+ *
1070
+ * @example
1071
+ * ```typescript
1072
+ * const nonce = await this.getServersUserNonce();
1073
+ * console.log(`Current servers nonce: ${nonce}`);
1074
+ * ```
1075
+ */
1076
+ /**
1077
+ * Retrieves the user's current nonce from the DataPortabilityServers contract.
1078
+ *
1079
+ * @remarks
1080
+ * Used for server-related operations (trust/untrust) to prevent replay attacks.
1081
+ * The nonce must be incremented with each server operation.
1082
+ *
1083
+ * @returns Promise resolving to the user's current nonce as a bigint
1084
+ * @throws {NonceError} When retrieving the nonce fails
1085
+ */
1086
+ async getServersUserNonce() {
1087
+ try {
1088
+ const userAddress = this.context.userAddress;
1089
+ const chainId = await this.context.publicClient.getChainId();
1090
+ const DataPortabilityServersAddress = getContractAddress(
1091
+ chainId,
1092
+ "DataPortabilityServers"
1093
+ );
1094
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
1095
+ const [nonce] = await this.context.publicClient.readContract({
1096
+ address: DataPortabilityServersAddress,
1097
+ abi: DataPortabilityServersAbi,
1098
+ functionName: "users",
1099
+ args: [userAddress]
1100
+ });
1101
+ return nonce;
1102
+ } catch (error) {
1103
+ throw new NonceError(
1104
+ `Failed to retrieve server nonce: ${error instanceof Error ? error.message : "Unknown error"}`
1105
+ );
1106
+ }
1107
+ }
1108
+ /**
1109
+ * Retrieves the user's current nonce from the DataPortabilityPermissions contract.
1110
+ * This nonce is used for permission-related operations (addPermission, addServerFilesAndPermissions).
1111
+ *
1112
+ * @returns Promise resolving to the current permissions nonce
1113
+ * @throws {NonceError} When reading nonce from contract fails
1114
+ * @private
1115
+ *
1116
+ * @example
1117
+ * ```typescript
1118
+ * const nonce = await this.getPermissionsUserNonce();
1119
+ * console.log(`Current permissions nonce: ${nonce}`);
1120
+ * ```
1121
+ */
1122
+ /**
1123
+ * Retrieves the user's current nonce from the DataPortabilityPermissions contract.
1124
+ *
1125
+ * @remarks
1126
+ * Used for permission-related operations (grant/revoke) to prevent replay attacks.
1127
+ * The nonce must be incremented with each permission operation.
1128
+ *
1129
+ * @returns Promise resolving to the user's current nonce as a bigint
1130
+ * @throws {NonceError} When retrieving the nonce fails
1131
+ */
1132
+ async getPermissionsUserNonce() {
1133
+ try {
1134
+ const userAddress = this.context.userAddress;
1135
+ const chainId = await this.context.publicClient.getChainId();
1136
+ const DataPortabilityPermissionsAddress = getContractAddress(
1137
+ chainId,
1138
+ "DataPortabilityPermissions"
1139
+ );
1140
+ const DataPortabilityPermissionsAbi = getAbi(
1141
+ "DataPortabilityPermissions"
1142
+ );
1143
+ const nonce = await this.context.publicClient.readContract({
1144
+ address: DataPortabilityPermissionsAddress,
1145
+ abi: DataPortabilityPermissionsAbi,
1146
+ functionName: "userNonce",
1147
+ args: [userAddress]
1148
+ });
1149
+ return nonce;
1150
+ } catch (error) {
1151
+ throw new NonceError(
1152
+ `Failed to retrieve permissions nonce: ${error instanceof Error ? error.message : "Unknown error"}`
1153
+ );
1154
+ }
1155
+ }
1156
+ /**
1157
+ * Composes the EIP-712 typed data for PermissionGrant (new simplified format).
1158
+ *
1159
+ * @param params - The parameters for composing the permission grant message
1160
+ * @param params.grantee - The recipient address for the permission grant
1161
+ * @param params.operation - The type of operation being granted permission for
1162
+ * @param params.files - Array of file IDs that the permission applies to
1163
+ * @param params.grantUrl - URL where the grant details are stored
1164
+ * @param params.serializedParameters - Serialized parameters for the operation
1165
+ * @param params.nonce - Unique number to prevent replay attacks
1166
+ * @returns Promise resolving to the typed data structure
1167
+ */
1168
+ async composePermissionGrantMessage(params) {
1169
+ const domain = await this.getPermissionDomain();
1170
+ console.debug(
1171
+ "\u{1F50D} Debug - Composing permission message with grantUrl:",
1172
+ params.grantUrl
1173
+ );
1174
+ const chainId = await this.context.publicClient.getChainId();
1175
+ const DataPortabilityGranteesAddress = getContractAddress(
1176
+ chainId,
1177
+ "DataPortabilityGrantees"
1178
+ );
1179
+ const DataPortabilityGranteesAbi = getAbi("DataPortabilityGrantees");
1180
+ const granteeId = await this.context.publicClient.readContract({
1181
+ address: DataPortabilityGranteesAddress,
1182
+ abi: DataPortabilityGranteesAbi,
1183
+ functionName: "granteeAddressToId",
1184
+ args: [params.grantee]
1185
+ });
1186
+ if (!params.grantUrl.startsWith("ipfs://") && params.grantUrl.includes("/ipfs/")) {
1187
+ const { extractIpfsHash } = await import("../utils/ipfs");
1188
+ const hash = extractIpfsHash(params.grantUrl);
1189
+ if (hash) {
1190
+ console.warn(
1191
+ `\u26A0\uFE0F Storing HTTP gateway URL on-chain instead of ipfs:// protocol. Found: ${params.grantUrl}. Consider using ipfs://${hash} for better protocol-agnostic on-chain storage.`
1192
+ );
1193
+ }
1194
+ }
1195
+ return {
1196
+ domain,
1197
+ types: {
1198
+ Permission: [
1199
+ { name: "nonce", type: "uint256" },
1200
+ { name: "granteeId", type: "uint256" },
1201
+ { name: "grant", type: "string" },
1202
+ { name: "fileIds", type: "uint256[]" }
1203
+ ]
1204
+ },
1205
+ primaryType: "Permission",
1206
+ message: {
1207
+ nonce: params.nonce,
1208
+ granteeId,
1209
+ grant: params.grantUrl,
1210
+ fileIds: params.files.map((fileId) => BigInt(fileId))
1211
+ }
1212
+ };
1213
+ }
1214
+ /**
1215
+ * Creates EIP-712 typed data structure for server files and permissions.
1216
+ *
1217
+ * @param params - Parameters for the server files and permissions message
1218
+ * @param params.granteeId - Grantee ID
1219
+ * @param params.grant - Grant URL or grant data
1220
+ * @param params.fileUrls - Array of file URLs
1221
+ * @param params.schemaIds - Schema IDs for each file
1222
+ * @param params.serverAddress - Server address
1223
+ * @param params.serverUrl - Server URL
1224
+ * @param params.serverPublicKey - Server public key
1225
+ * @param params.filePermissions - File permissions array
1226
+ * @param params.nonce - Unique number to prevent replay attacks
1227
+ * @returns Promise resolving to the typed data structure
1228
+ */
1229
+ async composeServerFilesAndPermissionMessage(params) {
1230
+ const domain = await this.getPermissionDomain();
1231
+ console.debug(
1232
+ "\u{1F50D} Debug - Composing server files and permission message with grant:",
1233
+ params.grant
1234
+ );
1235
+ if (!params.grant.startsWith("ipfs://") && params.grant.includes("/ipfs/")) {
1236
+ const { extractIpfsHash } = await import("../utils/ipfs");
1237
+ const hash = extractIpfsHash(params.grant);
1238
+ if (hash) {
1239
+ console.warn(
1240
+ `\u26A0\uFE0F Storing HTTP gateway URL on-chain instead of ipfs:// protocol. Found: ${params.grant}. Consider using ipfs://${hash} for better protocol-agnostic on-chain storage.`
1241
+ );
1242
+ }
1243
+ }
1244
+ return {
1245
+ domain,
1246
+ types: {
1247
+ Permission: [
1248
+ { name: "account", type: "address" },
1249
+ { name: "key", type: "string" }
1250
+ ],
1251
+ ServerFilesAndPermission: [
1252
+ { name: "nonce", type: "uint256" },
1253
+ { name: "granteeId", type: "uint256" },
1254
+ { name: "grant", type: "string" },
1255
+ { name: "fileUrls", type: "string[]" },
1256
+ { name: "schemaIds", type: "uint256[]" },
1257
+ { name: "serverAddress", type: "address" },
1258
+ { name: "serverUrl", type: "string" },
1259
+ { name: "serverPublicKey", type: "string" },
1260
+ { name: "filePermissions", type: "Permission[][]" }
1261
+ ]
1262
+ },
1263
+ primaryType: "ServerFilesAndPermission",
1264
+ message: {
1265
+ nonce: params.nonce,
1266
+ granteeId: params.granteeId,
1267
+ grant: params.grant,
1268
+ fileUrls: params.fileUrls,
1269
+ schemaIds: params.schemaIds.map((id) => BigInt(id)),
1270
+ serverAddress: params.serverAddress,
1271
+ serverUrl: params.serverUrl,
1272
+ serverPublicKey: params.serverPublicKey,
1273
+ filePermissions: params.filePermissions
1274
+ }
1275
+ };
1276
+ }
1277
+ /**
1278
+ * Gets the EIP-712 domain for PermissionGrant signatures.
1279
+ *
1280
+ * @returns Promise resolving to the EIP-712 domain configuration
1281
+ */
1282
+ async getPermissionDomain() {
1283
+ const chainId = await this.context.publicClient.getChainId();
1284
+ const DataPortabilityPermissionsAddress = getContractAddress(
1285
+ chainId,
1286
+ "DataPortabilityPermissions"
1287
+ );
1288
+ return {
1289
+ name: "VanaDataPortabilityPermissions",
1290
+ version: "1",
1291
+ chainId,
1292
+ verifyingContract: DataPortabilityPermissionsAddress
1293
+ };
1294
+ }
1295
+ /**
1296
+ * Signs typed data using the wallet client with signature caching.
1297
+ *
1298
+ * @param typedData - The EIP-712 typed data structure to sign
1299
+ * @returns Promise resolving to the cryptographic signature
1300
+ */
1301
+ async signTypedData(typedData) {
1302
+ this.assertWallet();
1303
+ try {
1304
+ const walletAddress = this.context.walletClient.account?.address ?? this.context.userAddress;
1305
+ return await withSignatureCache(
1306
+ this.context.platform.cache,
1307
+ walletAddress,
1308
+ typedData,
1309
+ async () => {
1310
+ const viemCompatibleTypedData = toViemTypedDataDefinition(typedData);
1311
+ return await this.context.walletClient.signTypedData({
1312
+ ...viemCompatibleTypedData,
1313
+ // Use the account if available, otherwise use the wallet address
1314
+ // This follows the same pattern used throughout this file
1315
+ account: this.context.walletClient.account ?? walletAddress
1316
+ });
1317
+ }
1318
+ );
1319
+ } catch (error) {
1320
+ if (error instanceof Error && error.message.includes("rejected")) {
1321
+ throw new UserRejectedRequestError();
1322
+ }
1323
+ throw new SignatureError(
1324
+ `Failed to sign typed data: ${error instanceof Error ? error.message : "Unknown error"}`,
1325
+ error
1326
+ );
1327
+ }
1328
+ }
1329
+ /**
1330
+ * Gets the user's address from the context.
1331
+ *
1332
+ * @returns The user's address
1333
+ */
1334
+ /**
1335
+ * Gets on-chain permission grant data without expensive off-chain resolution.
1336
+ *
1337
+ * @remarks
1338
+ * This method provides a fast, performance-focused way to retrieve permission grants
1339
+ * by querying only the subgraph without making expensive IPFS or individual contract calls.
1340
+ * It eliminates the N+1 query problem of the legacy `getUserPermissions()` method.
1341
+ *
1342
+ * The returned data contains all on-chain information but does NOT include resolved
1343
+ * operation details, parameters, or file IDs. Use `retrieveGrantFile()` separately
1344
+ * for specific grants when detailed data is needed.
1345
+ *
1346
+ * **Performance**: Completes in ~100-500ms regardless of permission count.
1347
+ * **Reliability**: Single point of failure (subgraph) with clear RPC fallback path.
1348
+ *
1349
+ * @param options - Options for retrieving permissions (limit, subgraph URL)
1350
+ * @returns A Promise that resolves to an array of `OnChainPermissionGrant` objects
1351
+ * @throws {BlockchainError} When subgraph query fails
1352
+ * @throws {NetworkError} When network requests fail
1353
+ * @example
1354
+ * ```typescript
1355
+ * // Fast: Get all on-chain permission data
1356
+ * const grants = await vana.permissions.getUserPermissionGrantsOnChain({ limit: 20 });
1357
+ *
1358
+ * // Display in UI immediately
1359
+ * grants.forEach(grant => {
1360
+ * console.log(`Permission ${grant.id}: ${grant.grantUrl}`);
1361
+ * });
1362
+ *
1363
+ * // Lazy load detailed data for specific permission when user clicks
1364
+ * const grantFile = await retrieveGrantFile(grants[0].grantUrl);
1365
+ * console.log(`Operation: ${grantFile.operation}`);
1366
+ * console.log(`Parameters:`, grantFile.parameters);
1367
+ * ```
1368
+ */
1369
+ async getUserPermissionGrantsOnChain(options = {}) {
1370
+ const { limit = 50, fetchAll = false, subgraphUrl } = options;
1371
+ const pageSize = fetchAll ? 100 : limit;
1372
+ const maxResults = fetchAll ? 1e4 : limit;
1373
+ try {
1374
+ const userAddress = this.context.userAddress;
1375
+ const graphqlEndpoint = subgraphUrl ?? this.context.subgraphUrl;
1376
+ if (!graphqlEndpoint) {
1377
+ throw new BlockchainError(
1378
+ "subgraphUrl is required. Please provide a valid subgraph endpoint or configure it in Vana constructor."
1379
+ );
1380
+ }
1381
+ const query = `
1382
+ query GetUserPermissions($userId: ID!, $first: Int!, $skip: Int!) {
1383
+ user(id: $userId) {
1384
+ id
1385
+ permissions(first: $first, skip: $skip, orderBy: addedAtBlock, orderDirection: desc) {
1386
+ id
1387
+ grant
1388
+ nonce
1389
+ signature
1390
+ startBlock
1391
+ endBlock
1392
+ addedAtBlock
1393
+ addedAtTimestamp
1394
+ transactionHash
1395
+ grantee {
1396
+ id
1397
+ address
1398
+ }
1399
+ }
1400
+ }
1401
+ }
1402
+ `;
1403
+ const allPermissions = [];
1404
+ let currentOffset = 0;
1405
+ if (!fetchAll) {
1406
+ const response = await fetch(graphqlEndpoint, {
1407
+ method: "POST",
1408
+ headers: {
1409
+ "Content-Type": "application/json"
1410
+ },
1411
+ body: JSON.stringify({
1412
+ query,
1413
+ variables: {
1414
+ userId: userAddress.toLowerCase(),
1415
+ first: limit,
1416
+ skip: 0
1417
+ }
1418
+ })
1419
+ });
1420
+ if (!response.ok) {
1421
+ throw new BlockchainError(
1422
+ `Subgraph request failed: ${response.status} ${response.statusText}`
1423
+ );
1424
+ }
1425
+ const result = await response.json();
1426
+ if (result.errors) {
1427
+ throw new BlockchainError(
1428
+ `Subgraph errors: ${result.errors.map((e) => e.message).join(", ")}`
1429
+ );
1430
+ }
1431
+ const userData = result.data?.user;
1432
+ if (!userData?.permissions?.length) {
1433
+ return [];
1434
+ }
1435
+ allPermissions.push(...userData.permissions);
1436
+ } else {
1437
+ while (allPermissions.length < maxResults) {
1438
+ const currentLimit = Math.min(
1439
+ pageSize,
1440
+ maxResults - allPermissions.length
1441
+ );
1442
+ const response = await fetch(graphqlEndpoint, {
1443
+ method: "POST",
1444
+ headers: {
1445
+ "Content-Type": "application/json"
1446
+ },
1447
+ body: JSON.stringify({
1448
+ query,
1449
+ variables: {
1450
+ userId: userAddress.toLowerCase(),
1451
+ first: currentLimit,
1452
+ skip: currentOffset
1453
+ }
1454
+ })
1455
+ });
1456
+ if (!response.ok) {
1457
+ throw new BlockchainError(
1458
+ `Subgraph request failed: ${response.status} ${response.statusText}`
1459
+ );
1460
+ }
1461
+ const result = await response.json();
1462
+ if (result.errors) {
1463
+ throw new BlockchainError(
1464
+ `Subgraph errors: ${result.errors.map((e) => e.message).join(", ")}`
1465
+ );
1466
+ }
1467
+ const userData = result.data?.user;
1468
+ if (!userData?.permissions?.length) {
1469
+ break;
1470
+ }
1471
+ allPermissions.push(...userData.permissions);
1472
+ if (userData.permissions.length < currentLimit) {
1473
+ break;
1474
+ }
1475
+ currentOffset += userData.permissions.length;
1476
+ }
1477
+ }
1478
+ const onChainGrants = allPermissions.map(
1479
+ (permission) => ({
1480
+ id: BigInt(permission.id),
1481
+ grantUrl: permission.grant,
1482
+ grantSignature: permission.signature,
1483
+ nonce: BigInt(permission.nonce),
1484
+ startBlock: BigInt(permission.startBlock),
1485
+ addedAtBlock: BigInt(permission.addedAtBlock),
1486
+ addedAtTimestamp: BigInt(permission.addedAtTimestamp ?? "0"),
1487
+ transactionHash: permission.transactionHash ?? "",
1488
+ grantor: userAddress,
1489
+ grantee: permission.grantee,
1490
+ active: !permission.endBlock || BigInt(permission.endBlock) === 0n
1491
+ // Active if no end block or end block is 0
1492
+ })
1493
+ );
1494
+ return onChainGrants.sort((a, b) => {
1495
+ if (a.id < b.id) return 1;
1496
+ if (a.id > b.id) return -1;
1497
+ return 0;
1498
+ });
1499
+ } catch (error) {
1500
+ if (error instanceof BlockchainError || error instanceof NetworkError) {
1501
+ throw error;
1502
+ }
1503
+ throw new BlockchainError(
1504
+ `Failed to fetch user permission grants: ${error instanceof Error ? error.message : "Unknown error"}`
1505
+ );
1506
+ }
1507
+ }
1508
+ /**
1509
+ * Registers a new server and immediately trusts it in the DataPortabilityServers contract.
1510
+ *
1511
+ * This is a combined operation that both registers a new data portability server
1512
+ * and adds it to the user's trusted servers list in a single transaction.
1513
+ * Trusted servers can handle data export and portability requests from the user.
1514
+ *
1515
+ * @param params - Parameters for adding and trusting the server
1516
+ * @param params.serverAddress - Ethereum address of the server
1517
+ * @param params.serverUrl - HTTPS URL where the server can be reached
1518
+ * @param params.publicKey - Server's public key for encryption (hex string)
1519
+ * @returns Promise resolving to transaction hash
1520
+ * @throws {UserRejectedRequestError} When user rejects the transaction
1521
+ * @throws {BlockchainError} When chain ID is unavailable or transaction fails
1522
+ * @throws {ServerAlreadyRegisteredError} When server address is already registered
1523
+ * @throws {Error} When wallet account is not available
1524
+ *
1525
+ * @example
1526
+ * ```typescript
1527
+ * // Add and trust a server by providing all required details
1528
+ * const txHash = await vana.permissions.addAndTrustServer({
1529
+ * owner: '0x1234567890abcdef1234567890abcdef12345678',
1530
+ * serverAddress: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
1531
+ * serverUrl: 'https://myserver.example.com',
1532
+ * publicKey: '0x456789abcdef456789abcdef456789abcdef456789abcdef'
1533
+ * });
1534
+ * console.log('Server added and trusted in transaction:', txHash);
1535
+ *
1536
+ * // Verify the server is now trusted
1537
+ * const trustedServers = await vana.permissions.getTrustedServers();
1538
+ * console.log('Now trusting servers:', trustedServers);
1539
+ * ```
1540
+ */
1541
+ async addAndTrustServer(params) {
1542
+ this.assertWallet();
1543
+ try {
1544
+ const chainId = await this.context.walletClient.getChainId();
1545
+ const DataPortabilityServersAddress = getContractAddress(
1546
+ chainId,
1547
+ "DataPortabilityServers"
1548
+ );
1549
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
1550
+ const account = this.context.walletClient?.account ?? this.context.userAddress;
1551
+ const userAddress = typeof account === "string" ? account : account.address;
1552
+ const normalizedUserAddress = getAddress(userAddress);
1553
+ const normalizedServerAddress = getAddress(params.serverAddress);
1554
+ const txHash = await this.context.walletClient.writeContract({
1555
+ address: DataPortabilityServersAddress,
1556
+ abi: DataPortabilityServersAbi,
1557
+ functionName: "addAndTrustServerByManager",
1558
+ args: [
1559
+ normalizedUserAddress,
1560
+ {
1561
+ serverAddress: normalizedServerAddress,
1562
+ serverUrl: params.serverUrl,
1563
+ publicKey: params.publicKey
1564
+ }
1565
+ ],
1566
+ account,
1567
+ chain: this.context.walletClient?.chain ?? null
1568
+ });
1569
+ const { tx } = await import("../utils/transactionHelpers");
1570
+ const txResult = tx({
1571
+ hash: txHash,
1572
+ from: userAddress,
1573
+ contract: "DataPortabilityServers",
1574
+ fn: "addAndTrustServerByManager"
1575
+ });
1576
+ if (!this.context.waitForTransactionEvents) {
1577
+ throw new BlockchainError("waitForTransactionEvents not configured");
1578
+ }
1579
+ const result = await this.context.waitForTransactionEvents(txResult);
1580
+ const event = result.expectedEvents.ServerTrusted;
1581
+ if (!event) {
1582
+ throw new BlockchainError(
1583
+ "ServerTrusted event not found in transaction"
1584
+ );
1585
+ }
1586
+ const receipt = await this.context.publicClient.getTransactionReceipt({
1587
+ hash: txHash
1588
+ });
1589
+ return {
1590
+ transactionHash: txHash,
1591
+ blockNumber: receipt.blockNumber,
1592
+ gasUsed: receipt.gasUsed,
1593
+ user: event.user,
1594
+ serverId: event.serverId,
1595
+ // bigint from event
1596
+ serverAddress: normalizedServerAddress,
1597
+ // derived from params
1598
+ serverUrl: params.serverUrl
1599
+ // provided in params
1600
+ };
1601
+ } catch (error) {
1602
+ if (error instanceof Error && error.message.includes("rejected")) {
1603
+ throw new UserRejectedRequestError();
1604
+ }
1605
+ throw new BlockchainError(
1606
+ `Failed to add and trust server: ${error instanceof Error ? error.message : "Unknown error"}`,
1607
+ error
1608
+ );
1609
+ }
1610
+ }
1611
+ /**
1612
+ * Trusts a server for data processing (legacy method).
1613
+ *
1614
+ * @param params - Parameters for trusting the server
1615
+ * @returns Promise resolving to transaction hash
1616
+ * @deprecated Use addAndTrustServer instead
1617
+ */
1618
+ async submitTrustServer(params) {
1619
+ this.assertWallet();
1620
+ try {
1621
+ const chainId = await this.context.walletClient.getChainId();
1622
+ const DataPortabilityServersAddress = getContractAddress(
1623
+ chainId,
1624
+ "DataPortabilityServers"
1625
+ );
1626
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
1627
+ const account = this.context.walletClient?.account ?? this.context.userAddress;
1628
+ const txHash = await this.context.walletClient.writeContract({
1629
+ address: DataPortabilityServersAddress,
1630
+ abi: DataPortabilityServersAbi,
1631
+ functionName: "trustServer",
1632
+ args: [BigInt(params.serverId)],
1633
+ account,
1634
+ chain: this.context.walletClient?.chain ?? null
1635
+ });
1636
+ const { tx } = await import("../utils/transactionHelpers");
1637
+ return tx({
1638
+ hash: txHash,
1639
+ from: typeof account === "string" ? account : account.address,
1640
+ contract: "DataPortabilityServers",
1641
+ fn: "trustServer"
1642
+ });
1643
+ } catch (error) {
1644
+ if (error instanceof Error && error.message.includes("rejected")) {
1645
+ throw new UserRejectedRequestError();
1646
+ }
1647
+ throw new BlockchainError(
1648
+ `Failed to trust server: ${error instanceof Error ? error.message : "Unknown error"}`,
1649
+ error
1650
+ );
1651
+ }
1652
+ }
1653
+ /**
1654
+ * Adds and trusts a server using a signature (gasless transaction).
1655
+ *
1656
+ * @param params - Parameters for adding and trusting the server
1657
+ * @returns Promise resolving to TransactionResult with ServerTrustResult event data
1658
+ */
1659
+ async submitAddAndTrustServerWithSignature(params, options) {
1660
+ this.assertWallet();
1661
+ try {
1662
+ const nonce = await this.getServersUserNonce();
1663
+ const serverAddress = getAddress(params.serverAddress);
1664
+ const addAndTrustServerInput = {
1665
+ nonce,
1666
+ serverAddress,
1667
+ publicKey: params.publicKey,
1668
+ serverUrl: params.serverUrl
1669
+ };
1670
+ const typedData = await this.composeAddAndTrustServerMessage(
1671
+ addAndTrustServerInput
1672
+ );
1673
+ console.debug("\u{1F50D} AddAndTrustServer Debug Info:", {
1674
+ nonce: nonce.toString(),
1675
+ serverAddress: params.serverAddress,
1676
+ publicKey: params.publicKey,
1677
+ serverUrl: params.serverUrl,
1678
+ domain: typedData.domain,
1679
+ typedDataMessage: typedData.message
1680
+ });
1681
+ const signature = await this.signTypedData(typedData);
1682
+ console.debug("\u{1F50D} Generated signature:", signature);
1683
+ let hash;
1684
+ if (this.context.relayer) {
1685
+ const request = {
1686
+ type: "signed",
1687
+ operation: "submitAddAndTrustServer",
1688
+ typedData,
1689
+ signature
1690
+ };
1691
+ const response = await this.context.relayer(request);
1692
+ if (response.type === "error") {
1693
+ throw new RelayerError(response.error);
1694
+ }
1695
+ if (response.type === "submitted") {
1696
+ hash = response.hash;
1697
+ } else if (response.type === "signed") {
1698
+ hash = response.hash;
1699
+ } else {
1700
+ throw new Error("Unexpected response type from relayer");
1701
+ }
1702
+ } else {
1703
+ hash = await this.submitAddAndTrustServerTransaction(
1704
+ addAndTrustServerInput,
1705
+ signature,
1706
+ options
1707
+ );
1708
+ }
1709
+ const account = this.context.walletClient?.account ?? this.context.userAddress;
1710
+ const { tx } = await import("../utils/transactionHelpers");
1711
+ return tx({
1712
+ hash,
1713
+ from: typeof account === "string" ? account : account.address,
1714
+ contract: "DataPortabilityServers",
1715
+ fn: "addAndTrustServerWithSignature"
1716
+ });
1717
+ } catch (error) {
1718
+ if (error instanceof Error) {
1719
+ if (error instanceof RelayerError || error instanceof UserRejectedRequestError || error instanceof SerializationError || error instanceof SignatureError || error instanceof NetworkError || error instanceof NonceError) {
1720
+ throw error;
1721
+ }
1722
+ throw new BlockchainError(
1723
+ `Add and trust server failed: ${error.message}`,
1724
+ error
1725
+ );
1726
+ }
1727
+ throw new BlockchainError(
1728
+ "Add and trust server failed with unknown error"
1729
+ );
1730
+ }
1731
+ }
1732
+ /**
1733
+ * Trusts a server using a signature (gasless transaction - legacy method).
1734
+ *
1735
+ * @param params - Parameters for trusting the server
1736
+ * @returns Promise resolving to transaction hash
1737
+ * @deprecated Use addAndTrustServerWithSignature instead
1738
+ * @throws {BlockchainError} When chain ID is not available
1739
+ * @throws {NonceError} When retrieving user nonce fails
1740
+ * @throws {SignatureError} When user rejects the signature request
1741
+ * @throws {RelayerError} When gasless submission fails
1742
+ * @throws {ServerUrlMismatchError} When server URL doesn't match existing registration
1743
+ * @throws {BlockchainError} When trust operation fails for any other reason
1744
+ */
1745
+ async submitTrustServerWithSignature(params, options) {
1746
+ this.assertWallet();
1747
+ try {
1748
+ const nonce = await this.getServersUserNonce();
1749
+ const trustServerInput = {
1750
+ nonce,
1751
+ serverId: params.serverId
1752
+ };
1753
+ const typedData = await this.composeTrustServerMessage(trustServerInput);
1754
+ const signature = await this.signTypedData(typedData);
1755
+ let hash;
1756
+ if (this.context.relayer) {
1757
+ const request = {
1758
+ type: "signed",
1759
+ operation: "submitTrustServer",
1760
+ typedData,
1761
+ signature
1762
+ };
1763
+ const response = await this.context.relayer(request);
1764
+ if (response.type === "error") {
1765
+ throw new RelayerError(response.error);
1766
+ }
1767
+ if (response.type === "submitted") {
1768
+ hash = response.hash;
1769
+ } else if (response.type === "signed") {
1770
+ hash = response.hash;
1771
+ } else {
1772
+ throw new Error("Unexpected response type from relayer");
1773
+ }
1774
+ } else {
1775
+ hash = await this.submitTrustServerTransaction(
1776
+ trustServerInput,
1777
+ signature,
1778
+ options
1779
+ );
1780
+ }
1781
+ const account = this.context.walletClient?.account ?? this.context.userAddress;
1782
+ const { tx } = await import("../utils/transactionHelpers");
1783
+ return tx({
1784
+ hash,
1785
+ from: typeof account === "string" ? account : account.address,
1786
+ contract: "DataPortabilityServers",
1787
+ fn: "trustServerWithSignature"
1788
+ });
1789
+ } catch (error) {
1790
+ if (error instanceof Error) {
1791
+ if (error instanceof RelayerError || error instanceof UserRejectedRequestError || error instanceof SerializationError || error instanceof SignatureError || error instanceof NetworkError || error instanceof NonceError) {
1792
+ throw error;
1793
+ }
1794
+ throw new BlockchainError(
1795
+ `Trust server failed: ${error.message}`,
1796
+ error
1797
+ );
1798
+ }
1799
+ throw new BlockchainError("Trust server failed with unknown error");
1800
+ }
1801
+ }
1802
+ /**
1803
+ * Submits a direct untrust server transaction (without signature).
1804
+ *
1805
+ * @param params - The untrust server parameters containing server details
1806
+ * @returns Promise resolving to the transaction hash
1807
+ */
1808
+ /**
1809
+ * Submits an untrust server transaction directly to the blockchain.
1810
+ *
1811
+ * @remarks
1812
+ * Internal method used for direct blockchain submission of untrust server operations
1813
+ * when relayer callbacks are not available.
1814
+ *
1815
+ * @param params - The untrust server parameters
1816
+ * @returns Promise resolving to TransactionResult for transaction tracking
1817
+ * @throws {BlockchainError} When contract submission fails
1818
+ */
1819
+ async submitDirectUntrustTransaction(params, options) {
1820
+ this.assertWallet();
1821
+ try {
1822
+ const chainId = await this.context.walletClient.getChainId();
1823
+ const DataPortabilityServersAddress = getContractAddress(
1824
+ chainId,
1825
+ "DataPortabilityServers"
1826
+ );
1827
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
1828
+ const account = this.context.walletClient?.account ?? this.context.userAddress;
1829
+ const txHash = await this.context.walletClient.writeContract({
1830
+ address: DataPortabilityServersAddress,
1831
+ abi: DataPortabilityServersAbi,
1832
+ functionName: "untrustServer",
1833
+ args: [BigInt(params.serverId)],
1834
+ account,
1835
+ chain: this.context.walletClient?.chain ?? null,
1836
+ ...options?.gas && { gas: options.gas },
1837
+ ...options?.nonce && { nonce: options.nonce },
1838
+ // Use EIP-1559 if available, otherwise fall back to legacy gasPrice
1839
+ ...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
1840
+ ...options.maxFeePerGas && {
1841
+ maxFeePerGas: options.maxFeePerGas
1842
+ },
1843
+ ...options.maxPriorityFeePerGas && {
1844
+ maxPriorityFeePerGas: options.maxPriorityFeePerGas
1845
+ }
1846
+ } : options?.gasPrice && { gasPrice: options.gasPrice }
1847
+ });
1848
+ const { tx } = await import("../utils/transactionHelpers");
1849
+ return tx({
1850
+ hash: txHash,
1851
+ from: typeof account === "string" ? account : account.address,
1852
+ contract: "DataPortabilityServers",
1853
+ fn: "untrustServer"
1854
+ });
1855
+ } catch (error) {
1856
+ if (error instanceof Error && error.message.includes("rejected")) {
1857
+ throw new UserRejectedRequestError();
1858
+ }
1859
+ throw new BlockchainError(
1860
+ `Failed to untrust server: ${error instanceof Error ? error.message : "Unknown error"}`,
1861
+ error
1862
+ );
1863
+ }
1864
+ }
1865
+ /**
1866
+ * Removes a server from the user's trusted servers list in the DataPortabilityServers contract.
1867
+ *
1868
+ * This revokes the server's authorization to handle data portability requests for the user.
1869
+ * The server remains registered in the system but will no longer be trusted by this user.
1870
+ *
1871
+ * @param params - Parameters for untrusting the server
1872
+ * @param params.serverId - The numeric ID of the server to untrust
1873
+ * @param options - Optional transaction options for gas parameters and timeout
1874
+ * @returns Promise resolving to transaction hash
1875
+ * @throws {Error} When wallet account is not available
1876
+ * @throws {NonceError} When retrieving user nonce fails
1877
+ * @throws {UserRejectedRequestError} When user rejects the transaction
1878
+ * @throws {ServerNotTrustedError} When the server is not currently trusted
1879
+ * @throws {BlockchainError} When untrust transaction fails
1880
+ *
1881
+ * @example
1882
+ * ```typescript
1883
+ * // Untrust a specific server
1884
+ * const txHash = await vana.permissions.untrustServer({
1885
+ * serverId: 1
1886
+ * });
1887
+ * console.log('Server untrusted in transaction:', txHash);
1888
+ *
1889
+ * // Verify the server is no longer trusted
1890
+ * const trustedServers = await vana.permissions.getTrustedServers();
1891
+ * console.log('Still trusting servers:', trustedServers);
1892
+ * ```
1893
+ */
1894
+ async submitUntrustServer(params, options) {
1895
+ this.assertWallet();
1896
+ const nonce = await this.getServersUserNonce();
1897
+ const untrustServerInput = {
1898
+ nonce,
1899
+ serverId: params.serverId
1900
+ };
1901
+ return await this.submitDirectUntrustTransaction(
1902
+ untrustServerInput,
1903
+ options
1904
+ );
1905
+ }
1906
+ /**
1907
+ * Untrusts a server using a signature (gasless transaction).
1908
+ *
1909
+ * @param params - Parameters for untrusting the server
1910
+ * @param params.serverId - The server's Ethereum address to untrust
1911
+ * @returns Promise resolving to transaction hash
1912
+ * @throws {Error} When wallet account is not available
1913
+ * @throws {NonceError} When retrieving user nonce fails
1914
+ * @throws {SignatureError} When user rejects the signature request
1915
+ * @throws {RelayerError} When gasless submission fails
1916
+ * @throws {BlockchainError} When untrust transaction fails
1917
+ */
1918
+ async submitUntrustServerWithSignature(params) {
1919
+ this.assertWallet();
1920
+ try {
1921
+ const nonce = await this.getServersUserNonce();
1922
+ const untrustServerInput = {
1923
+ nonce,
1924
+ serverId: params.serverId
1925
+ };
1926
+ const typedData = await this.composeUntrustServerMessage(untrustServerInput);
1927
+ const signature = await this.signTypedData(typedData);
1928
+ let hash;
1929
+ if (this.context.relayer) {
1930
+ const request = {
1931
+ type: "signed",
1932
+ operation: "submitUntrustServer",
1933
+ typedData,
1934
+ signature
1935
+ };
1936
+ const response = await this.context.relayer(request);
1937
+ if (response.type === "error") {
1938
+ throw new RelayerError(response.error);
1939
+ }
1940
+ if (response.type === "submitted") {
1941
+ hash = response.hash;
1942
+ } else if (response.type === "signed") {
1943
+ hash = response.hash;
1944
+ } else {
1945
+ throw new Error("Unexpected response type from relayer");
1946
+ }
1947
+ } else {
1948
+ hash = await this.submitSignedUntrustTransaction(typedData, signature);
1949
+ }
1950
+ const account = this.context.walletClient?.account ?? this.context.userAddress;
1951
+ const { tx } = await import("../utils/transactionHelpers");
1952
+ return tx({
1953
+ hash,
1954
+ from: typeof account === "string" ? account : account.address,
1955
+ contract: "DataPortabilityServers",
1956
+ fn: "untrustServerWithSignature"
1957
+ });
1958
+ } catch (error) {
1959
+ if (error instanceof Error) {
1960
+ if (error instanceof RelayerError || error instanceof UserRejectedRequestError || error instanceof SerializationError || error instanceof SignatureError || error instanceof NetworkError || error instanceof NonceError) {
1961
+ throw error;
1962
+ }
1963
+ throw new BlockchainError(
1964
+ `Untrust server failed: ${error.message}`,
1965
+ error
1966
+ );
1967
+ }
1968
+ throw new BlockchainError("Untrust server failed with unknown error");
1969
+ }
1970
+ }
1971
+ /**
1972
+ * Retrieves all servers trusted by a user from the DataPortabilityServers contract.
1973
+ *
1974
+ * Returns an array of server IDs that the specified user has explicitly trusted.
1975
+ * Trusted servers are those that users have authorized to handle their data portability requests.
1976
+ *
1977
+ * @param userAddress - Optional user address to query (defaults to current wallet user)
1978
+ * @returns Promise resolving to array of trusted server IDs (numeric)
1979
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
1980
+ * @throws {NetworkError} When unable to connect to the blockchain network
1981
+ *
1982
+ * @example
1983
+ * ```typescript
1984
+ * // Get trusted servers for current user
1985
+ * const myServers = await vana.permissions.getTrustedServers();
1986
+ * console.log(`I trust ${myServers.length} servers: ${myServers.join(', ')}`);
1987
+ *
1988
+ * // Get trusted servers for another user
1989
+ * const userServers = await vana.permissions.getTrustedServers("0x1234...");
1990
+ * console.log(`User trusts servers: ${userServers.join(', ')}`);
1991
+ * ```
1992
+ */
1993
+ async getTrustedServers(userAddress) {
1994
+ try {
1995
+ const user = userAddress ?? this.context.userAddress;
1996
+ const chainId = await this.context.publicClient.getChainId();
1997
+ const DataPortabilityServersAddress = getContractAddress(
1998
+ chainId,
1999
+ "DataPortabilityServers"
2000
+ );
2001
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
2002
+ const serverIds = await this.context.publicClient.readContract({
2003
+ address: DataPortabilityServersAddress,
2004
+ abi: DataPortabilityServersAbi,
2005
+ functionName: "userServerIdsValues",
2006
+ args: [user]
2007
+ });
2008
+ return serverIds.map((id) => Number(id));
2009
+ } catch (error) {
2010
+ throw new BlockchainError(
2011
+ `Failed to get trusted servers: ${error instanceof Error ? error.message : "Unknown error"}`,
2012
+ error
2013
+ );
2014
+ }
2015
+ }
2016
+ /**
2017
+ * Gets the total count of trusted servers for a user.
2018
+ *
2019
+ * @param userAddress - Optional user address (defaults to current user)
2020
+ * @returns Promise resolving to the number of trusted servers
2021
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
2022
+ */
2023
+ async getTrustedServersCount(userAddress) {
2024
+ try {
2025
+ const user = userAddress ?? this.context.userAddress;
2026
+ const chainId = await this.context.publicClient.getChainId();
2027
+ const DataPortabilityServersAddress = getContractAddress(
2028
+ chainId,
2029
+ "DataPortabilityServers"
2030
+ );
2031
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
2032
+ const count = await this.context.publicClient.readContract({
2033
+ address: DataPortabilityServersAddress,
2034
+ abi: DataPortabilityServersAbi,
2035
+ functionName: "userServerIdsLength",
2036
+ args: [user]
2037
+ });
2038
+ return Number(count);
2039
+ } catch (error) {
2040
+ throw new BlockchainError(
2041
+ `Failed to get trusted servers count: ${error instanceof Error ? error.message : "Unknown error"}`,
2042
+ error
2043
+ );
2044
+ }
2045
+ }
2046
+ /**
2047
+ * Gets trusted servers with pagination support.
2048
+ *
2049
+ * @param options - Query options including pagination parameters
2050
+ * @returns Promise resolving to paginated trusted servers
2051
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
2052
+ */
2053
+ async getTrustedServersPaginated(options = {}) {
2054
+ try {
2055
+ const user = options.userAddress ?? this.context.userAddress;
2056
+ const limit = options.limit ?? 50;
2057
+ const offset = options.offset ?? 0;
2058
+ const chainId = await this.context.publicClient.getChainId();
2059
+ const DataPortabilityServersAddress = getContractAddress(
2060
+ chainId,
2061
+ "DataPortabilityServers"
2062
+ );
2063
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
2064
+ const totalCount = await this.context.publicClient.readContract({
2065
+ address: DataPortabilityServersAddress,
2066
+ abi: DataPortabilityServersAbi,
2067
+ functionName: "userServerIdsLength",
2068
+ args: [user]
2069
+ });
2070
+ const total = Number(totalCount);
2071
+ if (offset >= total) {
2072
+ return {
2073
+ servers: [],
2074
+ total,
2075
+ offset,
2076
+ limit,
2077
+ hasMore: false
2078
+ };
2079
+ }
2080
+ const endIndex = Math.min(offset + limit, total);
2081
+ const serverIdCalls = [];
2082
+ for (let i = offset; i < endIndex; i++) {
2083
+ serverIdCalls.push({
2084
+ address: DataPortabilityServersAddress,
2085
+ abi: DataPortabilityServersAbi,
2086
+ functionName: "userServerIdsAt",
2087
+ args: [user, BigInt(i)]
2088
+ });
2089
+ }
2090
+ const serverIdResults = await gasAwareMulticall(this.context.publicClient, {
2091
+ contracts: serverIdCalls
2092
+ });
2093
+ const servers = serverIdResults.map((result) => Number(result)).filter((id) => id > 0);
2094
+ return {
2095
+ servers,
2096
+ total,
2097
+ offset,
2098
+ limit,
2099
+ hasMore: offset + limit < total
2100
+ };
2101
+ } catch (error) {
2102
+ throw new BlockchainError(
2103
+ `Failed to get paginated trusted servers: ${error instanceof Error ? error.message : "Unknown error"}`,
2104
+ error
2105
+ );
2106
+ }
2107
+ }
2108
+ /**
2109
+ * Gets trusted servers with their complete information.
2110
+ *
2111
+ * @param options - Query options
2112
+ * @returns Promise resolving to array of trusted server info
2113
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
2114
+ */
2115
+ async getTrustedServersWithInfo(options = {}) {
2116
+ try {
2117
+ const paginatedResult = await this.getTrustedServersPaginated(options);
2118
+ const chainId = await this.context.publicClient.getChainId();
2119
+ const DataPortabilityServersAddress = getContractAddress(
2120
+ chainId,
2121
+ "DataPortabilityServers"
2122
+ );
2123
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
2124
+ const serverInfoCalls = paginatedResult.servers.map(
2125
+ (serverId) => ({
2126
+ address: DataPortabilityServersAddress,
2127
+ abi: DataPortabilityServersAbi,
2128
+ functionName: "servers",
2129
+ args: [BigInt(serverId)]
2130
+ })
2131
+ );
2132
+ const serverInfoResults = await gasAwareMulticall(this.context.publicClient, {
2133
+ contracts: serverInfoCalls,
2134
+ allowFailure: true
2135
+ });
2136
+ return serverInfoResults.map((result, index) => {
2137
+ const serverId = paginatedResult.servers[index];
2138
+ if (result.status === "success" && result.result) {
2139
+ const serverInfo = result.result;
2140
+ return {
2141
+ id: BigInt(serverId),
2142
+ owner: serverInfo.owner,
2143
+ serverAddress: serverInfo.serverAddress,
2144
+ publicKey: serverInfo.publicKey,
2145
+ url: serverInfo.url,
2146
+ startBlock: 0n,
2147
+ // We don't have this info from the old method structure
2148
+ endBlock: 0n
2149
+ // 0 means still active
2150
+ };
2151
+ } else {
2152
+ return {
2153
+ id: BigInt(serverId),
2154
+ owner: "0x0000000000000000000000000000000000000000",
2155
+ serverAddress: "0x0000000000000000000000000000000000000000",
2156
+ publicKey: "",
2157
+ url: "",
2158
+ startBlock: 0n,
2159
+ endBlock: 0n
2160
+ };
2161
+ }
2162
+ });
2163
+ } catch (error) {
2164
+ throw new BlockchainError(
2165
+ `Failed to get trusted servers with info: ${error instanceof Error ? error.message : "Unknown error"}`,
2166
+ error
2167
+ );
2168
+ }
2169
+ }
2170
+ /**
2171
+ * Gets server information for multiple servers efficiently.
2172
+ *
2173
+ * @remarks
2174
+ * This method uses multicall to fetch information for multiple servers in a single
2175
+ * blockchain call, improving performance when querying many servers. Failed lookups
2176
+ * are returned separately for error handling.
2177
+ *
2178
+ * @param serverIds - Array of numeric server IDs to query
2179
+ * @returns Promise resolving to batch result containing successful lookups and failed IDs
2180
+ * @throws {BlockchainError} When reading from contract fails or chain is unavailable
2181
+ * @example
2182
+ * ```typescript
2183
+ * const result = await vana.permissions.getServerInfoBatch([1, 2, 3, 999]);
2184
+ *
2185
+ * // Process successful lookups
2186
+ * result.servers.forEach((server, id) => {
2187
+ * console.log(`Server ${id}: ${server.url}`);
2188
+ * });
2189
+ *
2190
+ * // Handle failed lookups
2191
+ * if (result.failed.length > 0) {
2192
+ * console.log(`Failed to fetch: ${result.failed.join(', ')}`);
2193
+ * }
2194
+ * ```
2195
+ */
2196
+ async getServerInfoBatch(serverIds) {
2197
+ if (serverIds.length === 0) {
2198
+ return {
2199
+ servers: /* @__PURE__ */ new Map(),
2200
+ failed: []
2201
+ };
2202
+ }
2203
+ try {
2204
+ const chainId = await this.context.publicClient.getChainId();
2205
+ const DataPortabilityServersAddress = getContractAddress(
2206
+ chainId,
2207
+ "DataPortabilityServers"
2208
+ );
2209
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
2210
+ const serverInfoCalls = serverIds.map(
2211
+ (serverId) => ({
2212
+ address: DataPortabilityServersAddress,
2213
+ abi: DataPortabilityServersAbi,
2214
+ functionName: "servers",
2215
+ args: [BigInt(serverId)]
2216
+ })
2217
+ );
2218
+ const serverInfoResults = await gasAwareMulticall(this.context.publicClient, {
2219
+ contracts: serverInfoCalls,
2220
+ allowFailure: true
2221
+ });
2222
+ const results = serverInfoResults.map((result, index) => {
2223
+ const serverId = serverIds[index];
2224
+ if (result.status === "success" && result.result) {
2225
+ const serverInfo = result.result;
2226
+ const server = {
2227
+ id: Number(serverInfo.id),
2228
+ owner: serverInfo.owner,
2229
+ url: serverInfo.url,
2230
+ serverAddress: serverInfo.serverAddress,
2231
+ publicKey: serverInfo.publicKey
2232
+ };
2233
+ return { serverId, server, success: true };
2234
+ } else {
2235
+ return { serverId, server: null, success: false };
2236
+ }
2237
+ });
2238
+ const servers = /* @__PURE__ */ new Map();
2239
+ const failed = [];
2240
+ for (const result of results) {
2241
+ if (result.success && result.server) {
2242
+ servers.set(result.serverId, result.server);
2243
+ } else {
2244
+ failed.push(result.serverId);
2245
+ }
2246
+ }
2247
+ return { servers, failed };
2248
+ } catch (error) {
2249
+ throw new BlockchainError(
2250
+ `Failed to batch get server info: ${error instanceof Error ? error.message : "Unknown error"}`,
2251
+ error
2252
+ );
2253
+ }
2254
+ }
2255
+ /**
2256
+ * Checks whether a specific server is trusted by a user.
2257
+ *
2258
+ * @remarks
2259
+ * This method queries the user's trusted server list and checks if the specified
2260
+ * server is present. Returns both the trust status and the index in the trust list
2261
+ * if trusted.
2262
+ *
2263
+ * @param serverId - Numeric server ID to check
2264
+ * @param userAddress - Optional user address (defaults to current user)
2265
+ * @returns Promise resolving to server trust status with trust index if applicable
2266
+ * @throws {BlockchainError} When reading from contract fails
2267
+ * @example
2268
+ * ```typescript
2269
+ * const status = await vana.permissions.checkServerTrustStatus(1);
2270
+ * if (status.isTrusted) {
2271
+ * console.log(`Server is trusted at index ${status.trustIndex}`);
2272
+ * } else {
2273
+ * console.log('Server is not trusted');
2274
+ * }
2275
+ * ```
2276
+ */
2277
+ async checkServerTrustStatus(serverId, userAddress) {
2278
+ try {
2279
+ const user = userAddress ?? this.context.userAddress;
2280
+ const trustedServers = await this.getTrustedServers(user);
2281
+ const trustIndex = trustedServers.findIndex(
2282
+ (server) => server === serverId
2283
+ );
2284
+ return {
2285
+ serverId,
2286
+ isTrusted: trustIndex !== -1,
2287
+ trustIndex: trustIndex !== -1 ? trustIndex : void 0
2288
+ };
2289
+ } catch (error) {
2290
+ throw new BlockchainError(
2291
+ `Failed to check server trust status: ${error instanceof Error ? error.message : "Unknown error"}`,
2292
+ error
2293
+ );
2294
+ }
2295
+ }
2296
+ /**
2297
+ * Composes EIP-712 typed data for AddAndTrustServer.
2298
+ *
2299
+ * @remarks
2300
+ * Creates the complete typed data structure required for EIP-712 signature generation
2301
+ * when adding and trusting a new server in a single transaction.
2302
+ *
2303
+ * @param input - The add and trust server input data containing server details
2304
+ * @returns Promise resolving to the typed data structure for server add and trust
2305
+ */
2306
+ async composeAddAndTrustServerMessage(input) {
2307
+ const domain = await this.getServersDomain();
2308
+ console.debug(domain);
2309
+ return {
2310
+ domain,
2311
+ types: {
2312
+ AddServer: [
2313
+ { name: "nonce", type: "uint256" },
2314
+ { name: "serverAddress", type: "address" },
2315
+ { name: "publicKey", type: "string" },
2316
+ { name: "serverUrl", type: "string" }
2317
+ ]
2318
+ },
2319
+ primaryType: "AddServer",
2320
+ message: input
2321
+ };
2322
+ }
2323
+ /**
2324
+ * Composes EIP-712 typed data for TrustServer.
2325
+ *
2326
+ * @param input - The trust server input data containing server details
2327
+ * @returns Promise resolving to the typed data structure for server trust
2328
+ */
2329
+ async composeTrustServerMessage(input) {
2330
+ const domain = await this.getServersDomain();
2331
+ return {
2332
+ domain,
2333
+ types: {
2334
+ TrustServer: [
2335
+ { name: "nonce", type: "uint256" },
2336
+ { name: "serverId", type: "uint256" }
2337
+ ]
2338
+ },
2339
+ primaryType: "TrustServer",
2340
+ message: input
2341
+ };
2342
+ }
2343
+ /**
2344
+ * Composes EIP-712 typed data for UntrustServer.
2345
+ *
2346
+ * @param input - The untrust server input data containing server details
2347
+ * @returns Promise resolving to the typed data structure for server untrust
2348
+ */
2349
+ async composeUntrustServerMessage(input) {
2350
+ const domain = await this.getServersDomain();
2351
+ return {
2352
+ domain,
2353
+ types: {
2354
+ UntrustServer: [
2355
+ { name: "nonce", type: "uint256" },
2356
+ { name: "serverId", type: "uint256" }
2357
+ ]
2358
+ },
2359
+ primaryType: "UntrustServer",
2360
+ message: input
2361
+ };
2362
+ }
2363
+ /**
2364
+ * Gets the EIP-712 domain for DataPortabilityServers signatures.
2365
+ *
2366
+ * @returns Promise resolving to the EIP-712 domain configuration
2367
+ */
2368
+ async getServersDomain() {
2369
+ const chainId = await this.context.publicClient.getChainId();
2370
+ const DataPortabilityServersAddress = getContractAddress(
2371
+ chainId,
2372
+ "DataPortabilityServers"
2373
+ );
2374
+ return {
2375
+ name: "VanaDataPortabilityServers",
2376
+ version: "1",
2377
+ chainId,
2378
+ verifyingContract: DataPortabilityServersAddress
2379
+ };
2380
+ }
2381
+ /**
2382
+ * Submits an add and trust server transaction directly to the blockchain.
2383
+ *
2384
+ * @param addAndTrustServerInput - The add and trust server input data containing server details
2385
+ * @param signature - The cryptographic signature for the transaction
2386
+ * @returns Promise resolving to the transaction hash
2387
+ */
2388
+ async submitAddAndTrustServerTransaction(addAndTrustServerInput, signature, options) {
2389
+ this.assertWallet();
2390
+ const chainId = await this.context.walletClient.getChainId();
2391
+ const DataPortabilityServersAddress = getContractAddress(
2392
+ chainId,
2393
+ "DataPortabilityServers"
2394
+ );
2395
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
2396
+ console.debug("\u{1F50D} Transaction Debug Info:", {
2397
+ chainId,
2398
+ contractAddress: DataPortabilityServersAddress,
2399
+ input: {
2400
+ nonce: addAndTrustServerInput.nonce.toString(),
2401
+ serverAddress: addAndTrustServerInput.serverAddress,
2402
+ publicKey: addAndTrustServerInput.publicKey,
2403
+ serverUrl: addAndTrustServerInput.serverUrl
2404
+ },
2405
+ signature
2406
+ });
2407
+ const formattedSignature = formatSignatureForContract(signature);
2408
+ const txHash = await this.context.walletClient.writeContract({
2409
+ address: DataPortabilityServersAddress,
2410
+ abi: DataPortabilityServersAbi,
2411
+ functionName: "addAndTrustServerWithSignature",
2412
+ args: [
2413
+ {
2414
+ nonce: addAndTrustServerInput.nonce,
2415
+ serverAddress: addAndTrustServerInput.serverAddress,
2416
+ publicKey: addAndTrustServerInput.publicKey,
2417
+ serverUrl: addAndTrustServerInput.serverUrl
2418
+ },
2419
+ formattedSignature
2420
+ ],
2421
+ account: this.context.walletClient?.account ?? this.context.userAddress,
2422
+ chain: this.context.walletClient?.chain ?? null,
2423
+ ...options && {
2424
+ gas: options.gas,
2425
+ nonce: options.nonce,
2426
+ // Use EIP-1559 gas pricing if available, otherwise legacy
2427
+ ...options.maxFeePerGas || options.maxPriorityFeePerGas ? {
2428
+ maxFeePerGas: options.maxFeePerGas,
2429
+ maxPriorityFeePerGas: options.maxPriorityFeePerGas
2430
+ } : options.gasPrice ? { gasPrice: options.gasPrice } : {}
2431
+ }
2432
+ });
2433
+ return txHash;
2434
+ }
2435
+ /**
2436
+ * Submits a trust server transaction directly to the blockchain.
2437
+ *
2438
+ * @param trustServerInput - The trust server input data containing server details
2439
+ * @param signature - The cryptographic signature for the transaction
2440
+ * @returns Promise resolving to the transaction hash
2441
+ */
2442
+ async submitTrustServerTransaction(trustServerInput, signature, options) {
2443
+ this.assertWallet();
2444
+ const chainId = await this.context.walletClient.getChainId();
2445
+ const DataPortabilityServersAddress = getContractAddress(
2446
+ chainId,
2447
+ "DataPortabilityServers"
2448
+ );
2449
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
2450
+ const formattedSignature = formatSignatureForContract(signature);
2451
+ const txHash = await this.context.walletClient.writeContract({
2452
+ address: DataPortabilityServersAddress,
2453
+ abi: DataPortabilityServersAbi,
2454
+ functionName: "trustServerWithSignature",
2455
+ args: [
2456
+ {
2457
+ nonce: trustServerInput.nonce,
2458
+ serverId: BigInt(trustServerInput.serverId)
2459
+ },
2460
+ formattedSignature
2461
+ ],
2462
+ account: this.context.walletClient?.account ?? this.context.userAddress,
2463
+ chain: this.context.walletClient?.chain ?? null,
2464
+ ...this.spreadTransactionOptions(options)
2465
+ });
2466
+ return txHash;
2467
+ }
2468
+ /**
2469
+ * Submits a revoke transaction directly to the blockchain with signature.
2470
+ *
2471
+ * @param typedData - The EIP-712 typed data structure for the revoke operation
2472
+ * @param signature - The cryptographic signature authorizing the revoke
2473
+ * @returns Promise resolving to the transaction hash
2474
+ */
2475
+ async submitDirectRevokeTransaction(typedData, signature, options) {
2476
+ this.assertWallet();
2477
+ const chainId = await this.context.walletClient.getChainId();
2478
+ const DataPortabilityPermissionsAddress = getContractAddress(
2479
+ chainId,
2480
+ "DataPortabilityPermissions"
2481
+ );
2482
+ const DataPortabilityPermissionsAbi = getAbi("DataPortabilityPermissions");
2483
+ const formattedSignature = formatSignatureForContract(signature);
2484
+ const txHash = await this.context.walletClient.writeContract({
2485
+ address: DataPortabilityPermissionsAddress,
2486
+ abi: DataPortabilityPermissionsAbi,
2487
+ functionName: "revokePermissionWithSignature",
2488
+ args: [typedData.message, formattedSignature],
2489
+ account: this.context.walletClient?.account ?? this.context.userAddress,
2490
+ chain: this.context.walletClient?.chain ?? null,
2491
+ ...options && {
2492
+ gas: options.gas,
2493
+ nonce: options.nonce,
2494
+ // Use EIP-1559 gas pricing if available, otherwise legacy
2495
+ ...options.maxFeePerGas || options.maxPriorityFeePerGas ? {
2496
+ maxFeePerGas: options.maxFeePerGas,
2497
+ maxPriorityFeePerGas: options.maxPriorityFeePerGas
2498
+ } : options.gasPrice ? { gasPrice: options.gasPrice } : {}
2499
+ }
2500
+ });
2501
+ return txHash;
2502
+ }
2503
+ /**
2504
+ * Submits an untrust server transaction with signature.
2505
+ *
2506
+ * @param typedData - The EIP-712 typed data structure for the untrust operation
2507
+ * @param signature - The cryptographic signature authorizing the untrust
2508
+ * @returns Promise resolving to the transaction hash
2509
+ */
2510
+ async submitSignedUntrustTransaction(typedData, signature, options) {
2511
+ this.assertWallet();
2512
+ const chainId = await this.context.walletClient.getChainId();
2513
+ const DataPortabilityServersAddress = getContractAddress(
2514
+ chainId,
2515
+ "DataPortabilityServers"
2516
+ );
2517
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
2518
+ const formattedSignature = formatSignatureForContract(signature);
2519
+ const contractMessage = {
2520
+ nonce: typedData.message.nonce,
2521
+ serverId: BigInt(typedData.message.serverId)
2522
+ };
2523
+ const txHash = await this.context.walletClient.writeContract({
2524
+ address: DataPortabilityServersAddress,
2525
+ abi: DataPortabilityServersAbi,
2526
+ functionName: "untrustServerWithSignature",
2527
+ args: [contractMessage, formattedSignature],
2528
+ account: this.context.walletClient?.account ?? this.context.userAddress,
2529
+ chain: this.context.walletClient?.chain ?? null,
2530
+ ...options && {
2531
+ gas: options.gas,
2532
+ nonce: options.nonce,
2533
+ // Use EIP-1559 gas pricing if available, otherwise legacy
2534
+ ...options.maxFeePerGas || options.maxPriorityFeePerGas ? {
2535
+ maxFeePerGas: options.maxFeePerGas,
2536
+ maxPriorityFeePerGas: options.maxPriorityFeePerGas
2537
+ } : options.gasPrice ? { gasPrice: options.gasPrice } : {}
2538
+ }
2539
+ });
2540
+ return txHash;
2541
+ }
2542
+ // ===========================
2543
+ // GRANTEE METHODS
2544
+ // ===========================
2545
+ /**
2546
+ * Registers a new grantee in the DataPortabilityGrantees contract.
2547
+ *
2548
+ * A grantee is an entity (like an application) that can receive data permissions
2549
+ * from users. Once registered, users can grant the grantee access to their data.
2550
+ *
2551
+ * This method supports gasless transactions via relayer when configured.
2552
+ * If no relayer is available, it falls back to direct wallet transactions.
2553
+ *
2554
+ * @param params - Parameters for registering the grantee
2555
+ * @param params.owner - The Ethereum address that will own this grantee registration
2556
+ * @param params.granteeAddress - The Ethereum address of the grantee (application)
2557
+ * @param params.publicKey - The public key used for data encryption/decryption (hex string)
2558
+ * @param options - Optional transaction options for gas parameters and timeout
2559
+ * @returns Promise resolving to the transaction hash
2560
+ * @throws {BlockchainError} When the grantee registration transaction fails
2561
+ * @throws {UserRejectedRequestError} When user rejects the transaction
2562
+ * @throws {RelayerError} When gasless transaction submission fails
2563
+ *
2564
+ * @example
2565
+ * ```typescript
2566
+ * const txHash = await vana.permissions.registerGrantee({
2567
+ * owner: "0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36",
2568
+ * granteeAddress: "0xApp1234567890123456789012345678901234567890",
2569
+ * publicKey: "0x1234567890abcdef..."
2570
+ * });
2571
+ * console.log(`Grantee registered in transaction: ${txHash}`);
2572
+ * ```
2573
+ */
2574
+ async submitRegisterGrantee(params, options) {
2575
+ try {
2576
+ let hash;
2577
+ if (this.context.relayer) {
2578
+ const request = {
2579
+ type: "direct",
2580
+ operation: "submitRegisterGrantee",
2581
+ params: {
2582
+ owner: params.owner,
2583
+ granteeAddress: params.granteeAddress,
2584
+ publicKey: params.publicKey
2585
+ }
2586
+ };
2587
+ const response = await this.context.relayer(request);
2588
+ if (response.type === "error") {
2589
+ throw new RelayerError(response.error);
2590
+ }
2591
+ if (response.type === "submitted") {
2592
+ hash = response.hash;
2593
+ } else if (response.type === "direct") {
2594
+ const result = response.result;
2595
+ hash = result.transactionHash;
2596
+ } else {
2597
+ throw new Error("Unexpected response type from relayer");
2598
+ }
2599
+ } else {
2600
+ this.assertWallet();
2601
+ const chainId = await this.context.walletClient.getChainId();
2602
+ const DataPortabilityGranteesAddress = getContractAddress(
2603
+ chainId,
2604
+ "DataPortabilityGrantees"
2605
+ );
2606
+ const DataPortabilityGranteesAbi = getAbi("DataPortabilityGrantees");
2607
+ const ownerAddress = getAddress(params.owner);
2608
+ const granteeAddress = getAddress(params.granteeAddress);
2609
+ const account2 = this.context.walletClient?.account ?? this.context.userAddress;
2610
+ hash = await this.context.walletClient.writeContract({
2611
+ address: DataPortabilityGranteesAddress,
2612
+ abi: DataPortabilityGranteesAbi,
2613
+ functionName: "registerGrantee",
2614
+ args: [ownerAddress, granteeAddress, params.publicKey],
2615
+ account: account2,
2616
+ chain: this.context.walletClient?.chain ?? null,
2617
+ ...this.spreadTransactionOptions(options)
2618
+ });
2619
+ }
2620
+ const account = this.context.walletClient?.account ?? this.context.userAddress;
2621
+ const { tx } = await import("../utils/transactionHelpers");
2622
+ return tx({
2623
+ hash,
2624
+ from: typeof account === "string" ? account : account.address,
2625
+ contract: "DataPortabilityGrantees",
2626
+ fn: "registerGrantee"
2627
+ });
2628
+ } catch (error) {
2629
+ if (error instanceof Error) {
2630
+ if (error instanceof RelayerError || error instanceof UserRejectedRequestError || error instanceof SerializationError || error instanceof SignatureError || error instanceof BlockchainError) {
2631
+ throw error;
2632
+ }
2633
+ if (error.name === "ContractFunctionExecutionError") {
2634
+ throw new BlockchainError(
2635
+ `Grantee registration failed: ${error.message}`,
2636
+ error
2637
+ );
2638
+ }
2639
+ if (error.name === "UserRejectedRequestError") {
2640
+ throw new UserRejectedRequestError(
2641
+ "User rejected the grantee registration transaction"
2642
+ );
2643
+ }
2644
+ throw new BlockchainError(
2645
+ `Failed to register grantee: ${error.message}`,
2646
+ error
2647
+ );
2648
+ }
2649
+ throw new BlockchainError(`Failed to register grantee: ${String(error)}`);
2650
+ }
2651
+ }
2652
+ // TODO: When DataPortabilityGrantees contract adds registerGranteeWithSignature function,
2653
+ // implement submitRegisterGranteeWithSignature and submitSignedRegisterGrantee methods
2654
+ // to support EIP-712 signed gasless transactions via relayer.
2655
+ // Current implementation above supports direct gasless transactions (relayer pays gas directly).
2656
+ /**
2657
+ * Retrieves all registered grantees from the DataPortabilityGrantees contract.
2658
+ *
2659
+ * Returns a paginated list of all grantees (applications) that have been registered
2660
+ * in the system and can receive data permissions from users.
2661
+ *
2662
+ * @param options - Query options for pagination and filtering
2663
+ * @param options.limit - Maximum number of grantees to return (default: 50)
2664
+ * @param options.offset - Number of grantees to skip for pagination (default: 0)
2665
+ * @returns Promise resolving to paginated grantees with metadata
2666
+ * @throws {BlockchainError} When contract read operation fails
2667
+ * @throws {NetworkError} When unable to connect to the blockchain network
2668
+ *
2669
+ * @example
2670
+ * ```typescript
2671
+ * // Get first 10 grantees
2672
+ * const result = await vana.permissions.getGrantees({
2673
+ * limit: 10,
2674
+ * offset: 0
2675
+ * });
2676
+ *
2677
+ * console.log(`Found ${result.total} total grantees`);
2678
+ * result.grantees.forEach(grantee => {
2679
+ * console.log(`Grantee ${grantee.id}: ${grantee.granteeAddress}`);
2680
+ * });
2681
+ *
2682
+ * // Check if there are more results
2683
+ * if (result.hasMore) {
2684
+ * console.log('More grantees available');
2685
+ * }
2686
+ * ```
2687
+ */
2688
+ async getGrantees(options = {}) {
2689
+ const chainId = await this.context.publicClient.getChainId();
2690
+ const DataPortabilityGranteesAddress = getContractAddress(
2691
+ chainId,
2692
+ "DataPortabilityGrantees"
2693
+ );
2694
+ const DataPortabilityGranteesAbi = getAbi("DataPortabilityGrantees");
2695
+ const totalCount = await this.context.publicClient.readContract({
2696
+ address: DataPortabilityGranteesAddress,
2697
+ abi: DataPortabilityGranteesAbi,
2698
+ functionName: "granteesCount"
2699
+ });
2700
+ const total = Number(totalCount);
2701
+ const limit = options.limit ?? 50;
2702
+ const offset = options.offset ?? 0;
2703
+ const includePermissions = options.includePermissions ?? true;
2704
+ const startId = total - offset;
2705
+ const endId = Math.max(startId - limit + 1, 1);
2706
+ const granteeIds = Array.from(
2707
+ { length: startId - endId + 1 },
2708
+ (_, i) => startId - i
2709
+ // Generate IDs in descending order
2710
+ );
2711
+ let grantees;
2712
+ if (includePermissions) {
2713
+ const granteePromises = granteeIds.map(
2714
+ (granteeId) => this.getGranteeById(granteeId)
2715
+ );
2716
+ const granteeResults = await Promise.all(granteePromises);
2717
+ grantees = granteeResults.filter(
2718
+ (grantee) => grantee !== null
2719
+ );
2720
+ } else {
2721
+ const granteeInfoPromises = granteeIds.map(
2722
+ async (granteeId) => {
2723
+ try {
2724
+ const granteeInfo = await this.context.publicClient.readContract({
2725
+ address: DataPortabilityGranteesAddress,
2726
+ abi: DataPortabilityGranteesAbi,
2727
+ functionName: "granteesV2",
2728
+ args: [BigInt(granteeId)]
2729
+ });
2730
+ const grantee = {
2731
+ id: granteeId,
2732
+ owner: granteeInfo.owner,
2733
+ address: granteeInfo.granteeAddress,
2734
+ publicKey: granteeInfo.publicKey,
2735
+ permissionIds: []
2736
+ // TypeScript infers number[] from Grantee type
2737
+ };
2738
+ return grantee;
2739
+ } catch (error) {
2740
+ console.warn(`Failed to fetch grantee ${granteeId}:`, error);
2741
+ return null;
2742
+ }
2743
+ }
2744
+ );
2745
+ const granteeInfoResults = await Promise.all(granteeInfoPromises);
2746
+ grantees = granteeInfoResults.filter(
2747
+ (grantee) => grantee !== null
2748
+ );
2749
+ }
2750
+ return {
2751
+ grantees,
2752
+ total,
2753
+ offset,
2754
+ limit,
2755
+ hasMore: offset + limit < total
2756
+ };
2757
+ }
2758
+ /**
2759
+ * Retrieves a specific grantee by their Ethereum wallet address.
2760
+ *
2761
+ * @remarks
2762
+ * Looks up a registered grantee (application) using their Ethereum address
2763
+ * and returns their complete registration information including all associated permissions.
2764
+ *
2765
+ * Returns `null` if the address is not registered as a grantee or if an error occurs.
2766
+ *
2767
+ * @param granteeAddress - Ethereum wallet address of the grantee to query
2768
+ * @returns Grantee information including ID, addresses, public key, and permission IDs, or `null` if not found
2769
+ *
2770
+ * @example
2771
+ * ```typescript
2772
+ * const granteeAddress = "0xApp1234567890123456789012345678901234567890";
2773
+ * const grantee = await vana.permissions.getGranteeByAddress(granteeAddress);
2774
+ *
2775
+ * if (grantee) {
2776
+ * console.log(`Found grantee ${grantee.id}`);
2777
+ * console.log(`Owner: ${grantee.owner}`);
2778
+ * console.log(`Public Key: ${grantee.publicKey}`);
2779
+ * console.log(`Permissions: ${grantee.permissionIds.join(', ')}`);
2780
+ * } else {
2781
+ * console.log('Grantee not found');
2782
+ * }
2783
+ * ```
2784
+ */
2785
+ async getGranteeByAddress(granteeAddress) {
2786
+ const chainId = await this.context.publicClient.getChainId();
2787
+ const DataPortabilityGranteesAddress = getContractAddress(
2788
+ chainId,
2789
+ "DataPortabilityGrantees"
2790
+ );
2791
+ const DataPortabilityGranteesAbi = getAbi("DataPortabilityGrantees");
2792
+ try {
2793
+ const granteeId = await this.context.publicClient.readContract({
2794
+ address: DataPortabilityGranteesAddress,
2795
+ abi: DataPortabilityGranteesAbi,
2796
+ functionName: "granteeAddressToId",
2797
+ args: [granteeAddress]
2798
+ });
2799
+ if (granteeId === 0n) {
2800
+ return null;
2801
+ }
2802
+ return await this.getGranteeById(Number(granteeId));
2803
+ } catch (error) {
2804
+ console.warn(`Failed to fetch grantee ${granteeAddress}:`, error);
2805
+ return null;
2806
+ }
2807
+ }
2808
+ /**
2809
+ * Retrieves a specific grantee by their unique ID.
2810
+ *
2811
+ * @remarks
2812
+ * Looks up a registered grantee (application) using their numeric ID assigned during
2813
+ * registration and returns their complete information including all associated permissions.
2814
+ *
2815
+ * Returns `null` if the grantee is not found or if an error occurs during fetching.
2816
+ *
2817
+ * @param granteeId - Unique numeric ID of the grantee (1-indexed)
2818
+ * @returns Grantee information including ID, addresses, public key, and permission IDs, or `null` if not found
2819
+ *
2820
+ * @example
2821
+ * ```typescript
2822
+ * const grantee = await vana.permissions.getGranteeById(1);
2823
+ *
2824
+ * if (grantee) {
2825
+ * console.log(`Grantee ID: ${grantee.id}`);
2826
+ * console.log(`Address: ${grantee.address}`);
2827
+ * console.log(`Owner: ${grantee.owner}`);
2828
+ * console.log(`Total permissions: ${grantee.permissionIds.length}`);
2829
+ * } else {
2830
+ * console.log('Grantee with ID 1 not found');
2831
+ * }
2832
+ * ```
2833
+ */
2834
+ async getGranteeById(granteeId) {
2835
+ const chainId = await this.context.publicClient.getChainId();
2836
+ const DataPortabilityGranteesAddress = getContractAddress(
2837
+ chainId,
2838
+ "DataPortabilityGrantees"
2839
+ );
2840
+ const DataPortabilityGranteesAbi = getAbi("DataPortabilityGrantees");
2841
+ try {
2842
+ const granteeInfoResult = await this.context.publicClient.readContract({
2843
+ address: DataPortabilityGranteesAddress,
2844
+ abi: DataPortabilityGranteesAbi,
2845
+ functionName: "granteesV2",
2846
+ args: [BigInt(granteeId)]
2847
+ });
2848
+ const granteeInfo = granteeInfoResult;
2849
+ const allPermissionIdsResult = await this.getGranteePermissionsPaginated(
2850
+ BigInt(granteeId)
2851
+ );
2852
+ const allPermissionIds = allPermissionIdsResult;
2853
+ return {
2854
+ id: granteeId,
2855
+ owner: granteeInfo.owner,
2856
+ address: granteeInfo.granteeAddress,
2857
+ publicKey: granteeInfo.publicKey,
2858
+ permissionIds: allPermissionIds.map((id) => Number(id))
2859
+ };
2860
+ } catch (error) {
2861
+ console.warn(`Failed to fetch grantee ${granteeId}:`, error);
2862
+ return null;
2863
+ }
2864
+ }
2865
+ // ===========================
2866
+ // DATA PORTABILITY SERVERS HELPER METHODS
2867
+ // ===========================
2868
+ /**
2869
+ * Get all trusted server IDs for a user
2870
+ *
2871
+ * @param userAddress - User address to query (defaults to current user)
2872
+ * @returns Promise resolving to array of server IDs
2873
+ */
2874
+ async getUserServerIds(userAddress) {
2875
+ try {
2876
+ const targetAddress = userAddress ?? this.context.userAddress;
2877
+ const chainId = await this.context.publicClient.getChainId();
2878
+ const DataPortabilityServersAddress = getContractAddress(
2879
+ chainId,
2880
+ "DataPortabilityServers"
2881
+ );
2882
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
2883
+ const serverIds = await this.context.publicClient.readContract({
2884
+ address: DataPortabilityServersAddress,
2885
+ abi: DataPortabilityServersAbi,
2886
+ functionName: "userServerIdsValues",
2887
+ args: [targetAddress]
2888
+ });
2889
+ return [...serverIds];
2890
+ } catch (error) {
2891
+ throw new BlockchainError(
2892
+ `Failed to get user server IDs: ${error instanceof Error ? error.message : "Unknown error"}`,
2893
+ error
2894
+ );
2895
+ }
2896
+ }
2897
+ /**
2898
+ * Get server ID at specific index for a user
2899
+ *
2900
+ * @param userAddress - User address to query
2901
+ * @param serverIndex - Index in the user's server list
2902
+ * @returns Promise resolving to server ID
2903
+ */
2904
+ async getUserServerIdAt(userAddress, serverIndex) {
2905
+ try {
2906
+ const chainId = await this.context.publicClient.getChainId();
2907
+ const DataPortabilityServersAddress = getContractAddress(
2908
+ chainId,
2909
+ "DataPortabilityServers"
2910
+ );
2911
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
2912
+ const serverId = await this.context.publicClient.readContract({
2913
+ address: DataPortabilityServersAddress,
2914
+ abi: DataPortabilityServersAbi,
2915
+ functionName: "userServerIdsAt",
2916
+ args: [userAddress, serverIndex]
2917
+ });
2918
+ return serverId;
2919
+ } catch (error) {
2920
+ throw new BlockchainError(
2921
+ `Failed to get user server ID at index: ${error instanceof Error ? error.message : "Unknown error"}`,
2922
+ error
2923
+ );
2924
+ }
2925
+ }
2926
+ /**
2927
+ * Get the number of trusted servers for a user
2928
+ *
2929
+ * @param userAddress - User address to query (defaults to current user)
2930
+ * @returns Promise resolving to number of trusted servers
2931
+ */
2932
+ async getUserServerCount(userAddress) {
2933
+ try {
2934
+ const targetAddress = userAddress ?? this.context.userAddress;
2935
+ const chainId = await this.context.publicClient.getChainId();
2936
+ const DataPortabilityServersAddress = getContractAddress(
2937
+ chainId,
2938
+ "DataPortabilityServers"
2939
+ );
2940
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
2941
+ const count = await this.context.publicClient.readContract({
2942
+ address: DataPortabilityServersAddress,
2943
+ abi: DataPortabilityServersAbi,
2944
+ functionName: "userServerIdsLength",
2945
+ args: [targetAddress]
2946
+ });
2947
+ return count;
2948
+ } catch (error) {
2949
+ throw new BlockchainError(
2950
+ `Failed to get user server count: ${error instanceof Error ? error.message : "Unknown error"}`,
2951
+ error
2952
+ );
2953
+ }
2954
+ }
2955
+ /**
2956
+ * Get detailed information about trusted servers for a user
2957
+ *
2958
+ * @param userAddress - User address to query (defaults to current user)
2959
+ * @returns Promise resolving to array of trusted server info
2960
+ */
2961
+ async getUserTrustedServers(userAddress) {
2962
+ try {
2963
+ const targetAddress = userAddress ?? this.context.userAddress;
2964
+ const chainId = await this.context.publicClient.getChainId();
2965
+ const DataPortabilityServersAddress = getContractAddress(
2966
+ chainId,
2967
+ "DataPortabilityServers"
2968
+ );
2969
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
2970
+ const servers = await this.context.publicClient.readContract({
2971
+ address: DataPortabilityServersAddress,
2972
+ abi: DataPortabilityServersAbi,
2973
+ functionName: "userServerValues",
2974
+ args: [targetAddress]
2975
+ });
2976
+ return [...servers];
2977
+ } catch (error) {
2978
+ throw new BlockchainError(
2979
+ `Failed to get user trusted servers: ${error instanceof Error ? error.message : "Unknown error"}`,
2980
+ error
2981
+ );
2982
+ }
2983
+ }
2984
+ /**
2985
+ * Get trusted server info for a specific server ID and user
2986
+ *
2987
+ * @param userAddress - User address to query
2988
+ * @param serverId - Server ID to get info for
2989
+ * @returns Promise resolving to trusted server info
2990
+ */
2991
+ async getUserTrustedServer(userAddress, serverId) {
2992
+ try {
2993
+ const chainId = await this.context.publicClient.getChainId();
2994
+ const DataPortabilityServersAddress = getContractAddress(
2995
+ chainId,
2996
+ "DataPortabilityServers"
2997
+ );
2998
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
2999
+ const serverInfo = await this.context.publicClient.readContract({
3000
+ address: DataPortabilityServersAddress,
3001
+ abi: DataPortabilityServersAbi,
3002
+ functionName: "userServers",
3003
+ args: [userAddress, serverId]
3004
+ });
3005
+ return serverInfo;
3006
+ } catch (error) {
3007
+ throw new BlockchainError(
3008
+ `Failed to get user trusted server: ${error instanceof Error ? error.message : "Unknown error"}`,
3009
+ error
3010
+ );
3011
+ }
3012
+ }
3013
+ /**
3014
+ * Get server information by server ID
3015
+ *
3016
+ * @param serverId - Server ID to get info for
3017
+ * @returns Promise resolving to server info
3018
+ */
3019
+ async getServerInfo(serverId) {
3020
+ try {
3021
+ const chainId = await this.context.publicClient.getChainId();
3022
+ const DataPortabilityServersAddress = getContractAddress(
3023
+ chainId,
3024
+ "DataPortabilityServers"
3025
+ );
3026
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
3027
+ const serverInfo = await this.context.publicClient.readContract({
3028
+ address: DataPortabilityServersAddress,
3029
+ abi: DataPortabilityServersAbi,
3030
+ functionName: "servers",
3031
+ args: [serverId]
3032
+ });
3033
+ return serverInfo;
3034
+ } catch (error) {
3035
+ throw new BlockchainError(
3036
+ `Failed to get server info: ${error instanceof Error ? error.message : "Unknown error"}`,
3037
+ error
3038
+ );
3039
+ }
3040
+ }
3041
+ /**
3042
+ * Get server information by server address
3043
+ *
3044
+ * @param serverAddress - Server address to get info for
3045
+ * @returns Promise resolving to server info
3046
+ */
3047
+ async getServerInfoByAddress(serverAddress) {
3048
+ try {
3049
+ const chainId = await this.context.publicClient.getChainId();
3050
+ const DataPortabilityServersAddress = getContractAddress(
3051
+ chainId,
3052
+ "DataPortabilityServers"
3053
+ );
3054
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
3055
+ const serverInfo = await this.context.publicClient.readContract({
3056
+ address: DataPortabilityServersAddress,
3057
+ abi: DataPortabilityServersAbi,
3058
+ functionName: "serverByAddress",
3059
+ args: [serverAddress]
3060
+ });
3061
+ return serverInfo;
3062
+ } catch (error) {
3063
+ throw new BlockchainError(
3064
+ `Failed to get server info by address: ${error instanceof Error ? error.message : "Unknown error"}`,
3065
+ error
3066
+ );
3067
+ }
3068
+ }
3069
+ // ===========================
3070
+ // DATA PORTABILITY PERMISSIONS HELPER METHODS
3071
+ // ===========================
3072
+ /**
3073
+ * Get all permission IDs for a user
3074
+ *
3075
+ * @param userAddress - User address to query (defaults to current user)
3076
+ * @returns Promise resolving to array of permission IDs
3077
+ */
3078
+ async getUserPermissionIds(userAddress) {
3079
+ try {
3080
+ const targetAddress = userAddress ?? this.context.userAddress;
3081
+ const chainId = await this.context.publicClient.getChainId();
3082
+ const DataPortabilityPermissionsAddress = getContractAddress(
3083
+ chainId,
3084
+ "DataPortabilityPermissions"
3085
+ );
3086
+ const DataPortabilityPermissionsAbi = getAbi(
3087
+ "DataPortabilityPermissions"
3088
+ );
3089
+ const permissionIds = await this.context.publicClient.readContract({
3090
+ address: DataPortabilityPermissionsAddress,
3091
+ abi: DataPortabilityPermissionsAbi,
3092
+ functionName: "userPermissionIdsValues",
3093
+ args: [targetAddress]
3094
+ });
3095
+ return [...permissionIds];
3096
+ } catch (error) {
3097
+ throw new BlockchainError(
3098
+ `Failed to get user permission IDs: ${error instanceof Error ? error.message : "Unknown error"}`,
3099
+ error
3100
+ );
3101
+ }
3102
+ }
3103
+ /**
3104
+ * Get permission ID at specific index for a user
3105
+ *
3106
+ * @param userAddress - User address to query
3107
+ * @param permissionIndex - Index in the user's permission list
3108
+ * @returns Promise resolving to permission ID
3109
+ */
3110
+ async getUserPermissionIdAt(userAddress, permissionIndex) {
3111
+ try {
3112
+ const chainId = await this.context.publicClient.getChainId();
3113
+ const DataPortabilityPermissionsAddress = getContractAddress(
3114
+ chainId,
3115
+ "DataPortabilityPermissions"
3116
+ );
3117
+ const DataPortabilityPermissionsAbi = getAbi(
3118
+ "DataPortabilityPermissions"
3119
+ );
3120
+ const permissionId = await this.context.publicClient.readContract({
3121
+ address: DataPortabilityPermissionsAddress,
3122
+ abi: DataPortabilityPermissionsAbi,
3123
+ functionName: "userPermissionIdsAt",
3124
+ args: [userAddress, permissionIndex]
3125
+ });
3126
+ return permissionId;
3127
+ } catch (error) {
3128
+ throw new BlockchainError(
3129
+ `Failed to get user permission ID at index: ${error instanceof Error ? error.message : "Unknown error"}`,
3130
+ error
3131
+ );
3132
+ }
3133
+ }
3134
+ /**
3135
+ * Get the number of permissions for a user
3136
+ *
3137
+ * @param userAddress - User address to query (defaults to current user)
3138
+ * @returns Promise resolving to number of permissions
3139
+ */
3140
+ async getUserPermissionCount(userAddress) {
3141
+ try {
3142
+ const targetAddress = userAddress ?? this.context.userAddress;
3143
+ const chainId = await this.context.publicClient.getChainId();
3144
+ const DataPortabilityPermissionsAddress = getContractAddress(
3145
+ chainId,
3146
+ "DataPortabilityPermissions"
3147
+ );
3148
+ const DataPortabilityPermissionsAbi = getAbi(
3149
+ "DataPortabilityPermissions"
3150
+ );
3151
+ const count = await this.context.publicClient.readContract({
3152
+ address: DataPortabilityPermissionsAddress,
3153
+ abi: DataPortabilityPermissionsAbi,
3154
+ functionName: "userPermissionIdsLength",
3155
+ args: [targetAddress]
3156
+ });
3157
+ return count;
3158
+ } catch (error) {
3159
+ throw new BlockchainError(
3160
+ `Failed to get user permission count: ${error instanceof Error ? error.message : "Unknown error"}`,
3161
+ error
3162
+ );
3163
+ }
3164
+ }
3165
+ /**
3166
+ * Get detailed permission information by permission ID
3167
+ *
3168
+ * @param permissionId - Permission ID to get info for
3169
+ * @returns Promise resolving to permission info
3170
+ */
3171
+ async getPermissionInfo(permissionId) {
3172
+ try {
3173
+ const chainId = await this.context.publicClient.getChainId();
3174
+ const DataPortabilityPermissionsAddress = getContractAddress(
3175
+ chainId,
3176
+ "DataPortabilityPermissions"
3177
+ );
3178
+ const DataPortabilityPermissionsAbi = getAbi(
3179
+ "DataPortabilityPermissions"
3180
+ );
3181
+ const permissionInfo = await this.context.publicClient.readContract({
3182
+ address: DataPortabilityPermissionsAddress,
3183
+ abi: DataPortabilityPermissionsAbi,
3184
+ functionName: "permissions",
3185
+ args: [permissionId]
3186
+ });
3187
+ return permissionInfo;
3188
+ } catch (error) {
3189
+ throw new BlockchainError(
3190
+ `Failed to get permission info: ${error instanceof Error ? error.message : "Unknown error"}`,
3191
+ error
3192
+ );
3193
+ }
3194
+ }
3195
+ /**
3196
+ * Get all permission IDs for a specific file
3197
+ *
3198
+ * @param fileId - File ID to get permissions for
3199
+ * @returns Promise resolving to array of permission IDs
3200
+ */
3201
+ async getFilePermissionIds(fileId) {
3202
+ try {
3203
+ const chainId = await this.context.publicClient.getChainId();
3204
+ const DataPortabilityPermissionsAddress = getContractAddress(
3205
+ chainId,
3206
+ "DataPortabilityPermissions"
3207
+ );
3208
+ const DataPortabilityPermissionsAbi = getAbi(
3209
+ "DataPortabilityPermissions"
3210
+ );
3211
+ const permissionIds = await this.context.publicClient.readContract({
3212
+ address: DataPortabilityPermissionsAddress,
3213
+ abi: DataPortabilityPermissionsAbi,
3214
+ functionName: "filePermissionIds",
3215
+ args: [fileId]
3216
+ });
3217
+ return [...permissionIds];
3218
+ } catch (error) {
3219
+ throw new BlockchainError(
3220
+ `Failed to get file permission IDs: ${error instanceof Error ? error.message : "Unknown error"}`,
3221
+ error
3222
+ );
3223
+ }
3224
+ }
3225
+ /**
3226
+ * Get all file IDs for a specific permission
3227
+ *
3228
+ * @param permissionId - Permission ID to get files for
3229
+ * @returns Promise resolving to array of file IDs
3230
+ */
3231
+ async getPermissionFileIds(permissionId) {
3232
+ try {
3233
+ const chainId = await this.context.publicClient.getChainId();
3234
+ const DataPortabilityPermissionsAddress = getContractAddress(
3235
+ chainId,
3236
+ "DataPortabilityPermissions"
3237
+ );
3238
+ const DataPortabilityPermissionsAbi = getAbi(
3239
+ "DataPortabilityPermissions"
3240
+ );
3241
+ const fileIds = await this.context.publicClient.readContract({
3242
+ address: DataPortabilityPermissionsAddress,
3243
+ abi: DataPortabilityPermissionsAbi,
3244
+ functionName: "permissionFileIds",
3245
+ args: [permissionId]
3246
+ });
3247
+ return [...fileIds];
3248
+ } catch (error) {
3249
+ throw new BlockchainError(
3250
+ `Failed to get permission file IDs: ${error instanceof Error ? error.message : "Unknown error"}`,
3251
+ error
3252
+ );
3253
+ }
3254
+ }
3255
+ /**
3256
+ * Retrieves detailed grant file data from IPFS or HTTP storage.
3257
+ *
3258
+ * @remarks
3259
+ * This method automatically uses the SDK's configured downloadRelayer to bypass CORS restrictions.
3260
+ * Use this instead of importing the standalone `retrieveGrantFile` utility.
3261
+ *
3262
+ * @param grantUrl - The grant file URL (from OnChainPermissionGrant.grantUrl)
3263
+ * @returns Promise resolving to the complete grant file with operation details
3264
+ * @throws {NetworkError} When all retrieval attempts fail
3265
+ * @example
3266
+ * ```typescript
3267
+ * const grants = await vana.permissions.getUserPermissionGrantsOnChain();
3268
+ * const grantFile = await vana.permissions.retrieveGrantFile(grants[0].grantUrl);
3269
+ * console.log(`Operation: ${grantFile.operation}`);
3270
+ * ```
3271
+ */
3272
+ async retrieveGrantFile(grantUrl) {
3273
+ const { retrieveGrantFile: retrieveGrantFileUtil } = await import("../utils/grantFiles");
3274
+ return retrieveGrantFileUtil(
3275
+ grantUrl,
3276
+ void 0,
3277
+ this.context.downloadRelayer
3278
+ );
3279
+ }
3280
+ /**
3281
+ * Get all permissions for a specific file (alias for getFilePermissionIds)
3282
+ *
3283
+ * @param fileId - File ID to get permissions for
3284
+ * @returns Promise resolving to array of permission IDs
3285
+ */
3286
+ async getFilePermissions(fileId) {
3287
+ const chainId = await this.context.publicClient.getChainId();
3288
+ const DataPortabilityPermissionsAddress = getContractAddress(
3289
+ chainId,
3290
+ "DataPortabilityPermissions"
3291
+ );
3292
+ const DataPortabilityPermissionsAbi = getAbi("DataPortabilityPermissions");
3293
+ const permissions = await this.context.publicClient.readContract({
3294
+ address: DataPortabilityPermissionsAddress,
3295
+ abi: DataPortabilityPermissionsAbi,
3296
+ functionName: "filePermissions",
3297
+ args: [fileId]
3298
+ });
3299
+ return [...permissions];
3300
+ }
3301
+ // ===========================
3302
+ // DATA PORTABILITY GRANTEES HELPER METHODS
3303
+ // ===========================
3304
+ /**
3305
+ * Retrieves detailed grantee information including all associated permissions.
3306
+ *
3307
+ * @remarks
3308
+ * Returns grantee metadata and associated permission IDs. Uses the newer
3309
+ * paginated contract method internally for efficient permission fetching.
3310
+ *
3311
+ * @param granteeId - Unique grantee identifier as bigint
3312
+ * @returns Grantee information containing owner address, grantee address, public key, and permission IDs
3313
+ * @throws {BlockchainError} When grantee ID is not found or contract read fails
3314
+ *
3315
+ * @example
3316
+ * ```typescript
3317
+ * const granteeInfo = await vana.permissions.getGranteeInfo(BigInt(1));
3318
+ * console.log(`Grantee ${granteeInfo.granteeAddress} has ${granteeInfo.permissionIds.length} permissions`);
3319
+ * ```
3320
+ */
3321
+ async getGranteeInfo(granteeId) {
3322
+ try {
3323
+ const grantee = await this.getGranteeById(Number(granteeId));
3324
+ if (!grantee) {
3325
+ throw new Error("Grantee not found");
3326
+ }
3327
+ return {
3328
+ owner: grantee.owner,
3329
+ granteeAddress: grantee.address,
3330
+ publicKey: grantee.publicKey,
3331
+ permissionIds: grantee.permissionIds.map((id) => BigInt(id))
3332
+ };
3333
+ } catch (error) {
3334
+ throw new BlockchainError(
3335
+ `Failed to get grantee info: ${error instanceof Error ? error.message : "Unknown error"}`,
3336
+ error
3337
+ );
3338
+ }
3339
+ }
3340
+ /**
3341
+ * Retrieves detailed grantee information by wallet address.
3342
+ *
3343
+ * @remarks
3344
+ * Looks up the grantee ID from the provided address, then fetches complete
3345
+ * grantee information including all associated permissions.
3346
+ *
3347
+ * @param granteeAddress - Ethereum wallet address of the grantee to query
3348
+ * @returns Grantee information containing owner address, grantee address, public key, and permission IDs
3349
+ * @throws {BlockchainError} When grantee address is not registered or contract read fails
3350
+ *
3351
+ * @example
3352
+ * ```typescript
3353
+ * const granteeInfo = await vana.permissions.getGranteeInfoByAddress("0x742d35Cc6634c0532925a3b844Bc9e8e1ee3b2De");
3354
+ * console.log(`Found grantee with ${granteeInfo.permissionIds.length} permissions`);
3355
+ * ```
3356
+ */
3357
+ async getGranteeInfoByAddress(granteeAddress) {
3358
+ try {
3359
+ const chainId = await this.context.publicClient.getChainId();
3360
+ const DataPortabilityGranteesAddress = getContractAddress(
3361
+ chainId,
3362
+ "DataPortabilityGrantees"
3363
+ );
3364
+ const DataPortabilityGranteesAbi = getAbi("DataPortabilityGrantees");
3365
+ const granteeIdResult = await this.context.publicClient.readContract({
3366
+ address: DataPortabilityGranteesAddress,
3367
+ abi: DataPortabilityGranteesAbi,
3368
+ functionName: "granteeAddressToId",
3369
+ args: [granteeAddress]
3370
+ });
3371
+ const granteeId = granteeIdResult;
3372
+ if (granteeId === 0n) {
3373
+ throw new Error("Grantee not found");
3374
+ }
3375
+ const grantee = await this.getGranteeById(Number(granteeId));
3376
+ if (!grantee) {
3377
+ throw new Error("Grantee not found");
3378
+ }
3379
+ return {
3380
+ owner: grantee.owner,
3381
+ granteeAddress: grantee.address,
3382
+ publicKey: grantee.publicKey,
3383
+ permissionIds: grantee.permissionIds.map((id) => BigInt(id))
3384
+ };
3385
+ } catch (error) {
3386
+ throw new BlockchainError(
3387
+ `Failed to get grantee info by address: ${error instanceof Error ? error.message : "Unknown error"}`,
3388
+ error
3389
+ );
3390
+ }
3391
+ }
3392
+ /**
3393
+ * Get all permission IDs for a specific grantee
3394
+ *
3395
+ * @param granteeId - Grantee ID to get permissions for
3396
+ * @returns Promise resolving to array of permission IDs
3397
+ */
3398
+ async getGranteePermissionIds(granteeId) {
3399
+ try {
3400
+ const chainId = await this.context.publicClient.getChainId();
3401
+ const DataPortabilityGranteesAddress = getContractAddress(
3402
+ chainId,
3403
+ "DataPortabilityGrantees"
3404
+ );
3405
+ const DataPortabilityGranteesAbi = getAbi("DataPortabilityGrantees");
3406
+ const permissionIds = await this.context.publicClient.readContract({
3407
+ address: DataPortabilityGranteesAddress,
3408
+ abi: DataPortabilityGranteesAbi,
3409
+ functionName: "granteePermissionIds",
3410
+ args: [granteeId]
3411
+ });
3412
+ return [...permissionIds];
3413
+ } catch (error) {
3414
+ throw new BlockchainError(
3415
+ `Failed to get grantee permission IDs: ${error instanceof Error ? error.message : "Unknown error"}`,
3416
+ error
3417
+ );
3418
+ }
3419
+ }
3420
+ /**
3421
+ * Get all permissions for a specific grantee (alias for getGranteePermissionIds)
3422
+ *
3423
+ * @param granteeId - Grantee ID to get permissions for
3424
+ * @returns Promise resolving to array of permission IDs
3425
+ */
3426
+ async getGranteePermissions(granteeId) {
3427
+ try {
3428
+ const chainId = await this.context.publicClient.getChainId();
3429
+ const DataPortabilityGranteesAddress = getContractAddress(
3430
+ chainId,
3431
+ "DataPortabilityGrantees"
3432
+ );
3433
+ const DataPortabilityGranteesAbi = getAbi("DataPortabilityGrantees");
3434
+ const permissions = await this.context.publicClient.readContract({
3435
+ address: DataPortabilityGranteesAddress,
3436
+ abi: DataPortabilityGranteesAbi,
3437
+ functionName: "granteePermissions",
3438
+ args: [granteeId]
3439
+ });
3440
+ return [...permissions];
3441
+ } catch (error) {
3442
+ throw new BlockchainError(
3443
+ `Failed to get grantee permissions: ${error instanceof Error ? error.message : "Unknown error"}`,
3444
+ error
3445
+ );
3446
+ }
3447
+ }
3448
+ /**
3449
+ * Retrieves permission IDs for a specific grantee with flexible pagination.
3450
+ *
3451
+ * @remarks
3452
+ * **Pagination Behavior:**
3453
+ * Returns different types based on parameters:
3454
+ * - Without offset/limit: Returns `bigint[]` of all permissions using batched multicall
3455
+ * - With offset/limit: Returns paginated object with `permissionIds`, `totalCount`, and `hasMore`
3456
+ *
3457
+ * Uses gas-aware multicall for efficient batch fetching when retrieving all permissions.
3458
+ *
3459
+ * @param granteeId - Grantee ID to get permissions for
3460
+ * @param options - Optional pagination parameters
3461
+ * @param options.offset - Zero-based starting index for pagination. Defaults to 0 when fetching all permissions. Required for single-page requests.
3462
+ * @param options.limit - Maximum number of permission IDs to return per page. Defaults to 100 when fetching all permissions. Required for single-page requests.
3463
+ * @returns When called without options: Array of all permission IDs as `bigint[]`.
3464
+ * When called with offset and limit: Paginated result object containing `permissionIds` array,
3465
+ * `totalCount`, and `hasMore` boolean.
3466
+ * @throws {BlockchainError} When contract read operation fails
3467
+ *
3468
+ * @example
3469
+ * ```typescript
3470
+ * // Fetch all permissions (no pagination params)
3471
+ * const allPermissions = await vana.permissions.getGranteePermissionsPaginated(BigInt(1));
3472
+ * console.log(`Total permissions: ${allPermissions.length}`);
3473
+ *
3474
+ * // Fetch a specific page (with pagination params)
3475
+ * const page = await vana.permissions.getGranteePermissionsPaginated(BigInt(1), {
3476
+ * offset: BigInt(0),
3477
+ * limit: BigInt(100)
3478
+ * });
3479
+ * console.log(`Fetched ${page.permissionIds.length} permissions`);
3480
+ * console.log(`Total: ${page.totalCount}, Has more: ${page.hasMore}`);
3481
+ *
3482
+ * // Fetch next page
3483
+ * if (page.hasMore) {
3484
+ * const nextPage = await vana.permissions.getGranteePermissionsPaginated(BigInt(1), {
3485
+ * offset: BigInt(100),
3486
+ * limit: BigInt(100)
3487
+ * });
3488
+ * }
3489
+ * ```
3490
+ */
3491
+ async getGranteePermissionsPaginated(granteeId, options) {
3492
+ try {
3493
+ const chainId = await this.context.publicClient.getChainId();
3494
+ const DataPortabilityGranteesAddress = getContractAddress(
3495
+ chainId,
3496
+ "DataPortabilityGrantees"
3497
+ );
3498
+ const DataPortabilityGranteesAbi = getAbi("DataPortabilityGrantees");
3499
+ const fetchOnlyOnePage = options?.offset !== void 0 && options?.limit !== void 0;
3500
+ if (fetchOnlyOnePage) {
3501
+ const result = await this.context.publicClient.readContract({
3502
+ address: DataPortabilityGranteesAddress,
3503
+ abi: DataPortabilityGranteesAbi,
3504
+ functionName: "granteePermissionsPaginated",
3505
+ args: [granteeId, options.offset, options.limit]
3506
+ });
3507
+ const [permissionIds, totalCount2, hasMore] = result;
3508
+ return {
3509
+ permissionIds: [...permissionIds],
3510
+ totalCount: totalCount2,
3511
+ hasMore
3512
+ };
3513
+ }
3514
+ const countResult = await this.context.publicClient.readContract({
3515
+ address: DataPortabilityGranteesAddress,
3516
+ abi: DataPortabilityGranteesAbi,
3517
+ functionName: "granteePermissionsPaginated",
3518
+ args: [granteeId, BigInt(0), BigInt(1)]
3519
+ });
3520
+ const [, totalCount] = countResult;
3521
+ if (totalCount === BigInt(0)) {
3522
+ return [];
3523
+ }
3524
+ const batchSize = options?.limit ?? BigInt(100);
3525
+ const startOffset = options?.offset ?? BigInt(0);
3526
+ const endOffset = totalCount;
3527
+ const numBatches = Math.ceil(
3528
+ Number(endOffset - startOffset) / Number(batchSize)
3529
+ );
3530
+ const paginationCalls = Array.from({ length: numBatches }, (_, i) => ({
3531
+ address: DataPortabilityGranteesAddress,
3532
+ abi: DataPortabilityGranteesAbi,
3533
+ functionName: "granteePermissionsPaginated",
3534
+ args: [
3535
+ granteeId,
3536
+ startOffset + BigInt(i) * batchSize,
3537
+ batchSize
3538
+ ]
3539
+ }));
3540
+ const results = await gasAwareMulticall(
3541
+ this.context.publicClient,
3542
+ {
3543
+ contracts: paginationCalls
3544
+ }
3545
+ );
3546
+ const allPermissionIds = [];
3547
+ for (const result of results) {
3548
+ const [permissionIds] = result;
3549
+ allPermissionIds.push(...permissionIds);
3550
+ }
3551
+ return allPermissionIds;
3552
+ } catch (error) {
3553
+ throw new BlockchainError(
3554
+ `Failed to get grantee permissions: ${error instanceof Error ? error.message : "Unknown error"}`,
3555
+ error
3556
+ );
3557
+ }
3558
+ }
3559
+ // ===== DataPortabilityServersImplementation Methods =====
3560
+ /**
3561
+ * Get all server IDs for a user
3562
+ *
3563
+ * @param userAddress - User address to get server IDs for
3564
+ * @returns Promise resolving to array of server IDs
3565
+ */
3566
+ async getUserServerIdsValues(userAddress) {
3567
+ try {
3568
+ const chainId = await this.context.publicClient.getChainId();
3569
+ const DataPortabilityServersAddress = getContractAddress(
3570
+ chainId,
3571
+ "DataPortabilityServers"
3572
+ );
3573
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
3574
+ const serverIds = await this.context.publicClient.readContract({
3575
+ address: DataPortabilityServersAddress,
3576
+ abi: DataPortabilityServersAbi,
3577
+ functionName: "userServerIdsValues",
3578
+ args: [userAddress]
3579
+ });
3580
+ return [...serverIds];
3581
+ } catch (error) {
3582
+ throw new BlockchainError(
3583
+ `Failed to get user server IDs: ${error instanceof Error ? error.message : "Unknown error"}`,
3584
+ error
3585
+ );
3586
+ }
3587
+ }
3588
+ /**
3589
+ * Get server ID at specific index for a user
3590
+ *
3591
+ * @param userAddress - User address
3592
+ * @param serverIndex - Index of the server ID
3593
+ * @returns Promise resolving to server ID
3594
+ */
3595
+ async getUserServerIdsAt(userAddress, serverIndex) {
3596
+ try {
3597
+ const chainId = await this.context.publicClient.getChainId();
3598
+ const DataPortabilityServersAddress = getContractAddress(
3599
+ chainId,
3600
+ "DataPortabilityServers"
3601
+ );
3602
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
3603
+ const serverId = await this.context.publicClient.readContract({
3604
+ address: DataPortabilityServersAddress,
3605
+ abi: DataPortabilityServersAbi,
3606
+ functionName: "userServerIdsAt",
3607
+ args: [userAddress, serverIndex]
3608
+ });
3609
+ return serverId;
3610
+ } catch (error) {
3611
+ throw new BlockchainError(
3612
+ `Failed to get user server ID at index: ${error instanceof Error ? error.message : "Unknown error"}`,
3613
+ error
3614
+ );
3615
+ }
3616
+ }
3617
+ /**
3618
+ * Get the number of servers a user has
3619
+ *
3620
+ * @param userAddress - User address
3621
+ * @returns Promise resolving to number of servers
3622
+ */
3623
+ async getUserServerIdsLength(userAddress) {
3624
+ try {
3625
+ const chainId = await this.context.publicClient.getChainId();
3626
+ const DataPortabilityServersAddress = getContractAddress(
3627
+ chainId,
3628
+ "DataPortabilityServers"
3629
+ );
3630
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
3631
+ const length = await this.context.publicClient.readContract({
3632
+ address: DataPortabilityServersAddress,
3633
+ abi: DataPortabilityServersAbi,
3634
+ functionName: "userServerIdsLength",
3635
+ args: [userAddress]
3636
+ });
3637
+ return length;
3638
+ } catch (error) {
3639
+ throw new BlockchainError(
3640
+ `Failed to get user server IDs length: ${error instanceof Error ? error.message : "Unknown error"}`,
3641
+ error
3642
+ );
3643
+ }
3644
+ }
3645
+ /**
3646
+ * Get trusted server info for a specific user and server ID
3647
+ *
3648
+ * @param userAddress - User address
3649
+ * @param serverId - Server ID
3650
+ * @returns Promise resolving to trusted server info
3651
+ */
3652
+ async getUserServers(userAddress, serverId) {
3653
+ try {
3654
+ const chainId = await this.context.publicClient.getChainId();
3655
+ const DataPortabilityServersAddress = getContractAddress(
3656
+ chainId,
3657
+ "DataPortabilityServers"
3658
+ );
3659
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
3660
+ const serverInfo = await this.context.publicClient.readContract({
3661
+ address: DataPortabilityServersAddress,
3662
+ abi: DataPortabilityServersAbi,
3663
+ functionName: "userServers",
3664
+ args: [userAddress, serverId]
3665
+ });
3666
+ return {
3667
+ id: serverInfo.id,
3668
+ owner: serverInfo.owner,
3669
+ serverAddress: serverInfo.serverAddress,
3670
+ publicKey: serverInfo.publicKey,
3671
+ url: serverInfo.url,
3672
+ startBlock: serverInfo.startBlock,
3673
+ endBlock: serverInfo.endBlock
3674
+ };
3675
+ } catch (error) {
3676
+ throw new BlockchainError(
3677
+ `Failed to get user server info: ${error instanceof Error ? error.message : "Unknown error"}`,
3678
+ error
3679
+ );
3680
+ }
3681
+ }
3682
+ /**
3683
+ * Get server info by server ID
3684
+ *
3685
+ * @param serverId - Server ID
3686
+ * @returns Promise resolving to server info
3687
+ */
3688
+ async getServers(serverId) {
3689
+ try {
3690
+ const chainId = await this.context.publicClient.getChainId();
3691
+ const DataPortabilityServersAddress = getContractAddress(
3692
+ chainId,
3693
+ "DataPortabilityServers"
3694
+ );
3695
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
3696
+ const serverInfo = await this.context.publicClient.readContract({
3697
+ address: DataPortabilityServersAddress,
3698
+ abi: DataPortabilityServersAbi,
3699
+ functionName: "servers",
3700
+ args: [serverId]
3701
+ });
3702
+ return {
3703
+ id: serverInfo.id,
3704
+ owner: serverInfo.owner,
3705
+ serverAddress: serverInfo.serverAddress,
3706
+ publicKey: serverInfo.publicKey,
3707
+ url: serverInfo.url
3708
+ };
3709
+ } catch (error) {
3710
+ throw new BlockchainError(
3711
+ `Failed to get server info: ${error instanceof Error ? error.message : "Unknown error"}`,
3712
+ error
3713
+ );
3714
+ }
3715
+ }
3716
+ /**
3717
+ * Get user info including nonce and trusted server IDs
3718
+ *
3719
+ * @param userAddress - User address
3720
+ * @returns Promise resolving to user info
3721
+ */
3722
+ async getUsers(userAddress) {
3723
+ try {
3724
+ const chainId = await this.context.publicClient.getChainId();
3725
+ const DataPortabilityServersAddress = getContractAddress(
3726
+ chainId,
3727
+ "DataPortabilityServers"
3728
+ );
3729
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
3730
+ const userInfo = await this.context.publicClient.readContract({
3731
+ address: DataPortabilityServersAddress,
3732
+ abi: DataPortabilityServersAbi,
3733
+ functionName: "users",
3734
+ args: [userAddress]
3735
+ });
3736
+ return {
3737
+ nonce: userInfo[0],
3738
+ trustedServerIds: [...userInfo[1]]
3739
+ };
3740
+ } catch (error) {
3741
+ throw new BlockchainError(
3742
+ `Failed to get user info: ${error instanceof Error ? error.message : "Unknown error"}`,
3743
+ error
3744
+ );
3745
+ }
3746
+ }
3747
+ /**
3748
+ * Update server URL
3749
+ *
3750
+ * @param serverId - Server ID to update
3751
+ * @param url - New URL for the server
3752
+ * @param options - Optional transaction options for gas parameters and timeout
3753
+ * @returns Promise resolving to transaction hash
3754
+ */
3755
+ async submitUpdateServer(serverId, url, options) {
3756
+ this.assertWallet();
3757
+ try {
3758
+ const chainId = await this.context.walletClient.getChainId();
3759
+ const DataPortabilityServersAddress = getContractAddress(
3760
+ chainId,
3761
+ "DataPortabilityServers"
3762
+ );
3763
+ const DataPortabilityServersAbi = getAbi("DataPortabilityServers");
3764
+ const account = this.context.walletClient?.account ?? this.context.userAddress;
3765
+ const hash = await this.context.walletClient.writeContract({
3766
+ address: DataPortabilityServersAddress,
3767
+ abi: DataPortabilityServersAbi,
3768
+ functionName: "updateServer",
3769
+ args: [serverId, url],
3770
+ chain: this.context.walletClient?.chain,
3771
+ account,
3772
+ ...options?.gas && { gas: options.gas },
3773
+ ...options?.nonce && { nonce: options.nonce },
3774
+ // Use EIP-1559 if available, otherwise fall back to legacy gasPrice
3775
+ ...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
3776
+ ...options.maxFeePerGas && {
3777
+ maxFeePerGas: options.maxFeePerGas
3778
+ },
3779
+ ...options.maxPriorityFeePerGas && {
3780
+ maxPriorityFeePerGas: options.maxPriorityFeePerGas
3781
+ }
3782
+ } : options?.gasPrice && { gasPrice: options.gasPrice }
3783
+ });
3784
+ const { tx } = await import("../utils/transactionHelpers");
3785
+ return tx({
3786
+ hash,
3787
+ from: typeof account === "string" ? account : account.address,
3788
+ contract: "DataPortabilityServers",
3789
+ fn: "updateServer"
3790
+ });
3791
+ } catch (error) {
3792
+ throw new BlockchainError(
3793
+ `Failed to update server: ${error instanceof Error ? error.message : "Unknown error"}`,
3794
+ error
3795
+ );
3796
+ }
3797
+ }
3798
+ // ===== DataPortabilityPermissionsImplementation Methods =====
3799
+ /**
3800
+ * Get all permission IDs for a user
3801
+ *
3802
+ * @param userAddress - User address to get permission IDs for
3803
+ * @returns Promise resolving to array of permission IDs
3804
+ */
3805
+ async getUserPermissionIdsValues(userAddress) {
3806
+ try {
3807
+ const chainId = await this.context.publicClient.getChainId();
3808
+ const DataPortabilityPermissionsAddress = getContractAddress(
3809
+ chainId,
3810
+ "DataPortabilityPermissions"
3811
+ );
3812
+ const DataPortabilityPermissionsAbi = getAbi(
3813
+ "DataPortabilityPermissions"
3814
+ );
3815
+ const permissionIds = await this.context.publicClient.readContract({
3816
+ address: DataPortabilityPermissionsAddress,
3817
+ abi: DataPortabilityPermissionsAbi,
3818
+ functionName: "userPermissionIdsValues",
3819
+ args: [userAddress]
3820
+ });
3821
+ return [...permissionIds];
3822
+ } catch (error) {
3823
+ throw new BlockchainError(
3824
+ `Failed to get user permission IDs: ${error instanceof Error ? error.message : "Unknown error"}`,
3825
+ error
3826
+ );
3827
+ }
3828
+ }
3829
+ /**
3830
+ * Get permission ID at specific index for a user
3831
+ *
3832
+ * @param userAddress - User address
3833
+ * @param permissionIndex - Index of the permission ID
3834
+ * @returns Promise resolving to permission ID
3835
+ */
3836
+ async getUserPermissionIdsAt(userAddress, permissionIndex) {
3837
+ try {
3838
+ const chainId = await this.context.publicClient.getChainId();
3839
+ const DataPortabilityPermissionsAddress = getContractAddress(
3840
+ chainId,
3841
+ "DataPortabilityPermissions"
3842
+ );
3843
+ const DataPortabilityPermissionsAbi = getAbi(
3844
+ "DataPortabilityPermissions"
3845
+ );
3846
+ const permissionId = await this.context.publicClient.readContract({
3847
+ address: DataPortabilityPermissionsAddress,
3848
+ abi: DataPortabilityPermissionsAbi,
3849
+ functionName: "userPermissionIdsAt",
3850
+ args: [userAddress, permissionIndex]
3851
+ });
3852
+ return permissionId;
3853
+ } catch (error) {
3854
+ throw new BlockchainError(
3855
+ `Failed to get user permission ID at index: ${error instanceof Error ? error.message : "Unknown error"}`,
3856
+ error
3857
+ );
3858
+ }
3859
+ }
3860
+ /**
3861
+ * Get the number of permissions a user has
3862
+ *
3863
+ * @param userAddress - User address
3864
+ * @returns Promise resolving to number of permissions
3865
+ */
3866
+ async getUserPermissionIdsLength(userAddress) {
3867
+ try {
3868
+ const chainId = await this.context.publicClient.getChainId();
3869
+ const DataPortabilityPermissionsAddress = getContractAddress(
3870
+ chainId,
3871
+ "DataPortabilityPermissions"
3872
+ );
3873
+ const DataPortabilityPermissionsAbi = getAbi(
3874
+ "DataPortabilityPermissions"
3875
+ );
3876
+ const length = await this.context.publicClient.readContract({
3877
+ address: DataPortabilityPermissionsAddress,
3878
+ abi: DataPortabilityPermissionsAbi,
3879
+ functionName: "userPermissionIdsLength",
3880
+ args: [userAddress]
3881
+ });
3882
+ return length;
3883
+ } catch (error) {
3884
+ throw new BlockchainError(
3885
+ `Failed to get user permission IDs length: ${error instanceof Error ? error.message : "Unknown error"}`,
3886
+ error
3887
+ );
3888
+ }
3889
+ }
3890
+ /**
3891
+ * Get permission info by permission ID
3892
+ *
3893
+ * @param permissionId - Permission ID
3894
+ * @returns Promise resolving to permission info
3895
+ */
3896
+ async getPermissions(permissionId) {
3897
+ try {
3898
+ const chainId = await this.context.publicClient.getChainId();
3899
+ const DataPortabilityPermissionsAddress = getContractAddress(
3900
+ chainId,
3901
+ "DataPortabilityPermissions"
3902
+ );
3903
+ const DataPortabilityPermissionsAbi = getAbi(
3904
+ "DataPortabilityPermissions"
3905
+ );
3906
+ const permissionInfo = await this.context.publicClient.readContract({
3907
+ address: DataPortabilityPermissionsAddress,
3908
+ abi: DataPortabilityPermissionsAbi,
3909
+ functionName: "permissions",
3910
+ args: [permissionId]
3911
+ });
3912
+ return {
3913
+ id: permissionInfo.id,
3914
+ grantor: permissionInfo.grantor,
3915
+ nonce: permissionInfo.nonce,
3916
+ granteeId: permissionInfo.granteeId,
3917
+ grant: permissionInfo.grant,
3918
+ startBlock: permissionInfo.startBlock,
3919
+ endBlock: permissionInfo.endBlock,
3920
+ fileIds: [...permissionInfo.fileIds]
3921
+ };
3922
+ } catch (error) {
3923
+ throw new BlockchainError(
3924
+ `Failed to get permission info: ${error instanceof Error ? error.message : "Unknown error"}`,
3925
+ error
3926
+ );
3927
+ }
3928
+ }
3929
+ /**
3930
+ * Submit permission with signature to the blockchain (supports gasless transactions)
3931
+ *
3932
+ * @param params - Parameters for adding permission
3933
+ * @returns Promise resolving to transaction hash
3934
+ * @throws {RelayerError} When gasless transaction submission fails
3935
+ * @throws {SignatureError} When user rejects the signature request
3936
+ * @throws {BlockchainError} When permission addition fails
3937
+ * @throws {NetworkError} When network communication fails
3938
+ */
3939
+ async submitAddPermission(params) {
3940
+ this.assertWallet();
3941
+ try {
3942
+ const nonce = await this.getPermissionsUserNonce();
3943
+ const addPermissionInput = {
3944
+ nonce,
3945
+ granteeId: params.granteeId,
3946
+ grant: params.grant,
3947
+ fileUrls: params.fileUrls,
3948
+ schemaIds: params.schemaIds,
3949
+ serverAddress: params.serverAddress,
3950
+ serverUrl: params.serverUrl,
3951
+ serverPublicKey: params.serverPublicKey,
3952
+ filePermissions: params.filePermissions
3953
+ };
3954
+ const typedData = await this.composeServerFilesAndPermissionMessage(addPermissionInput);
3955
+ const signature = await this.signTypedData(typedData);
3956
+ return await this.submitSignedAddPermission(typedData, signature);
3957
+ } catch (error) {
3958
+ if (error instanceof RelayerError || error instanceof UserRejectedRequestError || error instanceof SerializationError || error instanceof SignatureError || error instanceof NetworkError || error instanceof NonceError) {
3959
+ throw error;
3960
+ }
3961
+ throw new BlockchainError(
3962
+ `Failed to add permission: ${error instanceof Error ? error.message : "Unknown error"}`,
3963
+ error
3964
+ );
3965
+ }
3966
+ }
3967
+ /**
3968
+ * Submits an already-signed add permission transaction to the blockchain.
3969
+ * This method supports both relayer-based gasless transactions and direct transactions.
3970
+ *
3971
+ * @param typedData - The EIP-712 typed data for AddPermission
3972
+ * @param signature - The user's signature
3973
+ * @returns Promise resolving to TransactionResult with PermissionGrantResult event data
3974
+ * @throws {RelayerError} When gasless transaction submission fails
3975
+ * @throws {BlockchainError} When permission addition fails
3976
+ * @throws {NetworkError} When network communication fails
3977
+ */
3978
+ async submitSignedAddPermission(typedData, signature, options) {
3979
+ this.assertWallet();
3980
+ try {
3981
+ let hash;
3982
+ if (this.context.relayer) {
3983
+ const request = {
3984
+ type: "signed",
3985
+ operation: "submitAddPermission",
3986
+ typedData,
3987
+ signature
3988
+ };
3989
+ const response = await this.context.relayer(request);
3990
+ if (response.type === "error") {
3991
+ throw new RelayerError(response.error);
3992
+ }
3993
+ if (response.type === "submitted") {
3994
+ hash = response.hash;
3995
+ } else if (response.type === "signed") {
3996
+ hash = response.hash;
3997
+ } else {
3998
+ throw new Error("Unexpected response type from relayer");
3999
+ }
4000
+ } else {
4001
+ hash = await this.submitDirectAddPermissionTransaction(
4002
+ typedData,
4003
+ signature,
4004
+ options
4005
+ );
4006
+ }
4007
+ const account = this.context.walletClient?.account ?? this.context.userAddress;
4008
+ const { tx } = await import("../utils/transactionHelpers");
4009
+ return tx({
4010
+ hash,
4011
+ from: typeof account === "string" ? account : account.address,
4012
+ contract: "DataPortabilityPermissions",
4013
+ fn: "addPermission"
4014
+ });
4015
+ } catch (error) {
4016
+ if (error instanceof RelayerError || error instanceof NetworkError || error instanceof UserRejectedRequestError || error instanceof SignatureError || error instanceof NonceError) {
4017
+ throw error;
4018
+ }
4019
+ throw new BlockchainError(
4020
+ `Add permission submission failed: ${error instanceof Error ? error.message : "Unknown error"}`,
4021
+ error
4022
+ );
4023
+ }
4024
+ }
4025
+ /**
4026
+ * Submits server files and permissions with signature to the blockchain, supporting schema validation and gasless transactions.
4027
+ *
4028
+ * @remarks
4029
+ * This method validates files against their specified schemas before submission.
4030
+ * Schema validation ensures data conforms to expected formats before on-chain registration.
4031
+ * Files with schemaId = 0 bypass validation. The method supports atomic batch operations
4032
+ * where all files and permissions are registered in a single transaction.
4033
+ *
4034
+ * @param params - Parameters for adding server files and permissions
4035
+ * @param params.granteeId - The ID of the permission grantee
4036
+ * @param params.grant - Grant URL containing permission parameters (typically IPFS)
4037
+ * @param params.fileUrls - Array of file URLs to register
4038
+ * @param params.schemaIds - Schema IDs for each file. Use 0 for files without schema validation.
4039
+ * Array length must match fileUrls length.
4040
+ * @param params.serverAddress - Server wallet address for decryption permissions
4041
+ * @param params.serverUrl - Server endpoint URL
4042
+ * @param params.serverPublicKey - Server's public key for encryption.
4043
+ * Obtain via `vana.server.getIdentity(userAddress).publicKey`.
4044
+ * @param params.filePermissions - Nested array of permissions for each file
4045
+ * @param options - Optional transaction options for gas parameters and timeout.
4046
+ * Note: These options are only applied for direct blockchain transactions.
4047
+ * When using relayer callbacks (gasless transactions), these options are ignored.
4048
+ * @returns TransactionResult with immediate hash access and optional event data
4049
+ * @throws {Error} When schemaIds array length doesn't match fileUrls array length
4050
+ * @throws {SchemaValidationError} When file data doesn't match the specified schema.
4051
+ * Verify data structure matches schema definition from `vana.schemas.get(schemaId)`.
4052
+ * @throws {RelayerError} When gasless transaction submission fails.
4053
+ * Retry without relayer configuration to submit direct transaction.
4054
+ * @throws {SignatureError} When user rejects the signature request
4055
+ * @throws {BlockchainError} When server files and permissions addition fails
4056
+ * @throws {NetworkError} When network communication fails.
4057
+ * Check network connection or configure alternative gateways.
4058
+ *
4059
+ * @example
4060
+ * ```typescript
4061
+ * // Submit with custom gas parameters and timeout
4062
+ * const result = await vana.permissions.submitAddServerFilesAndPermissions({
4063
+ * granteeId: BigInt(1),
4064
+ * grant: "ipfs://QmXxx...",
4065
+ * fileUrls: ["https://storage.example.com/data.json"],
4066
+ * schemaIds: [123], // LinkedIn profile schema ID
4067
+ * serverAddress: "0x742d35Cc6634C0532925a3b844Bc9e7595f0b0Bb",
4068
+ * serverUrl: "https://server.example.com",
4069
+ * serverPublicKey: serverInfo.publicKey,
4070
+ * filePermissions: [[{
4071
+ * account: "0x742d35Cc6634C0532925a3b844Bc9e7595f0b0Bb",
4072
+ * key: encryptedKey
4073
+ * }]]
4074
+ * }, {
4075
+ * maxFeePerGas: 100n * 10n ** 9n, // 100 gwei
4076
+ * maxPriorityFeePerGas: 2n * 10n ** 9n, // 2 gwei tip
4077
+ * });
4078
+ *
4079
+ * // Wait for confirmation with custom timeout
4080
+ * const receipt = await vana.waitForTransactionReceipt(result, {
4081
+ * timeout: 180000 // 3 minutes
4082
+ * });
4083
+ * console.log(`Transaction confirmed: ${receipt.transactionHash}`);
4084
+ * ```
4085
+ */
4086
+ async submitAddServerFilesAndPermissions(params, options) {
4087
+ this.assertWallet();
4088
+ try {
4089
+ if (params.schemaIds.length !== params.fileUrls.length) {
4090
+ throw new Error(
4091
+ `schemaIds array length (${params.schemaIds.length}) must match fileUrls array length (${params.fileUrls.length})`
4092
+ );
4093
+ }
4094
+ const nonce = await this.getPermissionsUserNonce();
4095
+ const serverFilesAndPermissionInput = {
4096
+ nonce,
4097
+ granteeId: params.granteeId,
4098
+ grant: params.grant,
4099
+ fileUrls: params.fileUrls,
4100
+ schemaIds: params.schemaIds,
4101
+ serverAddress: params.serverAddress,
4102
+ serverUrl: params.serverUrl,
4103
+ serverPublicKey: params.serverPublicKey,
4104
+ filePermissions: params.filePermissions
4105
+ };
4106
+ const typedData = await this.composeServerFilesAndPermissionMessage(
4107
+ serverFilesAndPermissionInput
4108
+ );
4109
+ const signature = await this.signTypedData(typedData);
4110
+ return await this.submitSignedAddServerFilesAndPermissions(
4111
+ typedData,
4112
+ signature,
4113
+ options
4114
+ );
4115
+ } catch (error) {
4116
+ if (error instanceof RelayerError || error instanceof UserRejectedRequestError || error instanceof SerializationError || error instanceof SignatureError || error instanceof NetworkError || error instanceof NonceError) {
4117
+ throw error;
4118
+ }
4119
+ throw new BlockchainError(
4120
+ `Failed to add server files and permissions: ${error instanceof Error ? error.message : "Unknown error"}`,
4121
+ error
4122
+ );
4123
+ }
4124
+ }
4125
+ /**
4126
+ * Submits an already-signed add server files and permissions transaction to the blockchain.
4127
+ *
4128
+ * @remarks
4129
+ * This method returns a TransactionResult that provides immediate access to the transaction hash.
4130
+ * The eventData field may contain parsed event details after transaction confirmation.
4131
+ *
4132
+ * @param typedData - The EIP-712 typed data for AddServerFilesAndPermissions
4133
+ * @param signature - The user's signature
4134
+ * @param options - Optional transaction options for gas parameters and timeout.
4135
+ * Note: These options are only applied for direct blockchain transactions.
4136
+ * When using relayer callbacks (gasless transactions), these options are ignored.
4137
+ * @returns TransactionResult with immediate hash access and optional event data
4138
+ * @throws {RelayerError} When gasless transaction submission fails
4139
+ * @throws {BlockchainError} When server files and permissions addition fails
4140
+ * @throws {NetworkError} When network communication fails
4141
+ *
4142
+ * @example
4143
+ * ```typescript
4144
+ * const tx = await vana.permissions.submitSignedAddServerFilesAndPermissions(
4145
+ * typedData,
4146
+ * signature
4147
+ * );
4148
+ * console.log(`Transaction submitted: ${tx.hash}`);
4149
+ *
4150
+ * // Wait for confirmation and get the permission ID
4151
+ * const { permissionId } = await tx.waitForEvents();
4152
+ * console.log(`Permission created with ID: ${permissionId}`);
4153
+ * ```
4154
+ */
4155
+ async submitSignedAddServerFilesAndPermissions(typedData, signature, options) {
4156
+ this.assertWallet();
4157
+ try {
4158
+ let hash;
4159
+ if (this.context.relayer) {
4160
+ console.debug(
4161
+ "\u{1F680} Using relayer for submitAddServerFilesAndPermissions"
4162
+ );
4163
+ const request = {
4164
+ type: "signed",
4165
+ operation: "submitAddServerFilesAndPermissions",
4166
+ typedData,
4167
+ signature
4168
+ };
4169
+ const response = await this.context.relayer(request);
4170
+ if (response.type === "error") {
4171
+ throw new RelayerError(response.error);
4172
+ }
4173
+ if (response.type === "submitted") {
4174
+ hash = response.hash;
4175
+ } else if (response.type === "signed") {
4176
+ hash = response.hash;
4177
+ } else {
4178
+ throw new Error("Unexpected response type from relayer");
4179
+ }
4180
+ } else {
4181
+ console.debug(
4182
+ "\u{1F4DD} Using direct transaction for submitAddServerFilesAndPermissions"
4183
+ );
4184
+ hash = await this.submitDirectAddServerFilesAndPermissionsTransaction(
4185
+ typedData,
4186
+ signature,
4187
+ options
4188
+ );
4189
+ }
4190
+ const account = this.context.walletClient?.account ?? this.context.userAddress;
4191
+ const { tx } = await import("../utils/transactionHelpers");
4192
+ return tx({
4193
+ hash,
4194
+ from: typeof account === "string" ? account : account.address,
4195
+ contract: "DataPortabilityPermissions",
4196
+ fn: "addServerFilesAndPermissions"
4197
+ });
4198
+ } catch (error) {
4199
+ if (error instanceof RelayerError || error instanceof NetworkError || error instanceof UserRejectedRequestError || error instanceof SignatureError || error instanceof NonceError) {
4200
+ throw error;
4201
+ }
4202
+ throw new BlockchainError(
4203
+ `Add server files and permissions submission failed: ${error instanceof Error ? error.message : "Unknown error"}`,
4204
+ error
4205
+ );
4206
+ }
4207
+ }
4208
+ /**
4209
+ * Submit permission revocation with signature to the blockchain
4210
+ *
4211
+ * @param permissionId - Permission ID to revoke
4212
+ * @param options - Optional transaction options for gas parameters and timeout
4213
+ * @returns Promise resolving to transaction hash
4214
+ */
4215
+ async submitRevokePermission(permissionId, options) {
4216
+ this.assertWallet();
4217
+ try {
4218
+ const chainId = await this.context.walletClient.getChainId();
4219
+ const DataPortabilityPermissionsAddress = getContractAddress(
4220
+ chainId,
4221
+ "DataPortabilityPermissions"
4222
+ );
4223
+ const DataPortabilityPermissionsAbi = getAbi(
4224
+ "DataPortabilityPermissions"
4225
+ );
4226
+ const { account } = this.context.walletClient;
4227
+ if (!account) {
4228
+ throw new Error("No wallet account connected");
4229
+ }
4230
+ const hash = await this.context.walletClient.writeContract({
4231
+ address: DataPortabilityPermissionsAddress,
4232
+ abi: DataPortabilityPermissionsAbi,
4233
+ functionName: "revokePermission",
4234
+ args: [permissionId],
4235
+ chain: this.context.walletClient?.chain,
4236
+ account,
4237
+ ...options?.gas && { gas: options.gas },
4238
+ ...options?.nonce && { nonce: options.nonce },
4239
+ // Use EIP-1559 if available, otherwise fall back to legacy gasPrice
4240
+ ...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
4241
+ ...options.maxFeePerGas && {
4242
+ maxFeePerGas: options.maxFeePerGas
4243
+ },
4244
+ ...options.maxPriorityFeePerGas && {
4245
+ maxPriorityFeePerGas: options.maxPriorityFeePerGas
4246
+ }
4247
+ } : options?.gasPrice && { gasPrice: options.gasPrice }
4248
+ });
4249
+ const { tx } = await import("../utils/transactionHelpers");
4250
+ return tx({
4251
+ hash,
4252
+ from: typeof account === "string" ? account : account.address,
4253
+ contract: "DataPortabilityPermissions",
4254
+ fn: "revokePermission"
4255
+ });
4256
+ } catch (error) {
4257
+ throw new BlockchainError(
4258
+ `Failed to revoke permission: ${error instanceof Error ? error.message : "Unknown error"}`,
4259
+ error
4260
+ );
4261
+ }
4262
+ }
4263
+ /**
4264
+ * Submits a signed add permission transaction directly to the blockchain.
4265
+ *
4266
+ * @param typedData - The typed data structure for the permission addition
4267
+ * @param signature - The cryptographic signature authorizing the transaction
4268
+ * @returns Promise resolving to the transaction hash
4269
+ */
4270
+ async submitDirectAddPermissionTransaction(typedData, signature, options) {
4271
+ this.assertWallet();
4272
+ const chainId = await this.context.walletClient.getChainId();
4273
+ const DataPortabilityPermissionsAddress = getContractAddress(
4274
+ chainId,
4275
+ "DataPortabilityPermissions"
4276
+ );
4277
+ const DataPortabilityPermissionsAbi = getAbi("DataPortabilityPermissions");
4278
+ const permissionInput = {
4279
+ nonce: typedData.message.nonce,
4280
+ granteeId: typedData.message.granteeId,
4281
+ grant: typedData.message.grant,
4282
+ fileIds: typedData.message.fileIds ?? []
4283
+ };
4284
+ const formattedSignature = formatSignatureForContract(signature);
4285
+ const hash = await this.context.walletClient.writeContract({
4286
+ address: DataPortabilityPermissionsAddress,
4287
+ abi: DataPortabilityPermissionsAbi,
4288
+ functionName: "addPermission",
4289
+ args: [permissionInput, formattedSignature],
4290
+ account: this.context.walletClient?.account ?? this.context.userAddress,
4291
+ chain: this.context.walletClient?.chain ?? null,
4292
+ ...this.spreadTransactionOptions(options)
4293
+ });
4294
+ return hash;
4295
+ }
4296
+ /**
4297
+ * Submits a signed add server files and permissions transaction directly to the blockchain.
4298
+ *
4299
+ * @param typedData - The typed data structure for the server files and permissions addition
4300
+ * @param signature - The cryptographic signature authorizing the transaction
4301
+ * @returns Promise resolving to the transaction hash
4302
+ */
4303
+ async submitDirectAddServerFilesAndPermissionsTransaction(typedData, signature, options) {
4304
+ this.assertWallet();
4305
+ const chainId = await this.context.publicClient.getChainId();
4306
+ const DataPortabilityPermissionsAddress = getContractAddress(
4307
+ chainId,
4308
+ "DataPortabilityPermissions"
4309
+ );
4310
+ const DataPortabilityPermissionsAbi = getAbi("DataPortabilityPermissions");
4311
+ const serverFilesAndPermissionInput = {
4312
+ nonce: typedData.message.nonce,
4313
+ granteeId: typedData.message.granteeId,
4314
+ grant: typedData.message.grant,
4315
+ fileUrls: typedData.message.fileUrls,
4316
+ schemaIds: typedData.message.schemaIds,
4317
+ serverAddress: typedData.message.serverAddress,
4318
+ serverUrl: typedData.message.serverUrl,
4319
+ serverPublicKey: typedData.message.serverPublicKey,
4320
+ filePermissions: typedData.message.filePermissions
4321
+ };
4322
+ const formattedSignature = formatSignatureForContract(signature);
4323
+ const hash = await this.context.walletClient.writeContract({
4324
+ address: DataPortabilityPermissionsAddress,
4325
+ abi: DataPortabilityPermissionsAbi,
4326
+ functionName: "addServerFilesAndPermissions",
4327
+ args: [serverFilesAndPermissionInput, formattedSignature],
4328
+ account: this.context.walletClient?.account ?? this.context.userAddress,
4329
+ chain: this.context.walletClient?.chain ?? null,
4330
+ ...options?.value && { value: options.value },
4331
+ ...this.spreadTransactionOptions(options)
4332
+ });
4333
+ return hash;
4334
+ }
4335
+ }
4336
+ export {
4337
+ PermissionsController
4338
+ };
4339
+ //# sourceMappingURL=permissions.js.map