@opendatalabs/vana-sdk 0.1.0-alpha.d7fc764 → 0.1.0-alpha.dc68f39

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 (667) hide show
  1. package/dist/__tests__/waitForTransactionEvents.test.d.ts +1 -0
  2. package/dist/browser.d.ts +4 -2
  3. package/dist/chains/definitions.cjs +9 -6
  4. package/dist/chains/definitions.cjs.map +1 -1
  5. package/dist/chains/definitions.d.ts +9 -11
  6. package/dist/chains/definitions.js +9 -6
  7. package/dist/chains/definitions.js.map +1 -1
  8. package/dist/chains/index.d.ts +5 -2
  9. package/dist/chains.browser.d.ts +8 -2
  10. package/dist/chains.d.ts +8 -2
  11. package/dist/chains.node.d.ts +8 -2
  12. package/dist/config/addresses.d.ts +8 -24
  13. package/dist/config/chains.d.ts +9 -13
  14. package/dist/config/default-services.cjs +60 -0
  15. package/dist/config/default-services.cjs.map +1 -0
  16. package/dist/config/default-services.d.ts +46 -0
  17. package/dist/config/default-services.js +33 -0
  18. package/dist/config/default-services.js.map +1 -0
  19. package/dist/config/default-services.test.d.ts +1 -0
  20. package/dist/config/features.d.ts +1 -3
  21. package/dist/config/tests/addresses.test.d.ts +1 -0
  22. package/dist/contracts/contractController.cjs +3 -3
  23. package/dist/contracts/contractController.cjs.map +1 -1
  24. package/dist/contracts/contractController.d.ts +11 -28
  25. package/dist/contracts/contractController.js +4 -7
  26. package/dist/contracts/contractController.js.map +1 -1
  27. package/dist/contracts/tests/contractController.test.d.ts +1 -0
  28. package/dist/controllers/__tests__/schemas-edge-cases.test.d.ts +1 -0
  29. package/dist/controllers/base.cjs +83 -0
  30. package/dist/controllers/base.cjs.map +1 -0
  31. package/dist/controllers/base.d.ts +84 -0
  32. package/dist/controllers/base.js +59 -0
  33. package/dist/controllers/base.js.map +1 -0
  34. package/dist/controllers/data-error-handling.test.d.ts +1 -0
  35. package/dist/controllers/data.cjs +415 -172
  36. package/dist/controllers/data.cjs.map +1 -1
  37. package/dist/controllers/data.d.ts +149 -76
  38. package/dist/controllers/data.js +415 -172
  39. package/dist/controllers/data.js.map +1 -1
  40. package/dist/controllers/permissions.cjs +508 -257
  41. package/dist/controllers/permissions.cjs.map +1 -1
  42. package/dist/controllers/permissions.d.ts +1348 -25
  43. package/dist/controllers/permissions.js +508 -257
  44. package/dist/controllers/permissions.js.map +1 -1
  45. package/dist/controllers/protocol.cjs +15 -11
  46. package/dist/controllers/protocol.cjs.map +1 -1
  47. package/dist/controllers/protocol.d.ts +7 -35
  48. package/dist/controllers/protocol.js +15 -14
  49. package/dist/controllers/protocol.js.map +1 -1
  50. package/dist/controllers/schemas.cjs +69 -54
  51. package/dist/controllers/schemas.cjs.map +1 -1
  52. package/dist/controllers/schemas.d.ts +9 -36
  53. package/dist/controllers/schemas.js +69 -54
  54. package/dist/controllers/schemas.js.map +1 -1
  55. package/dist/controllers/server-additional.test.d.ts +1 -0
  56. package/dist/controllers/server.cjs +15 -10
  57. package/dist/controllers/server.cjs.map +1 -1
  58. package/dist/controllers/server.d.ts +7 -33
  59. package/dist/controllers/server.js +15 -10
  60. package/dist/controllers/server.js.map +1 -1
  61. package/dist/core/apiClient.cjs +15 -12
  62. package/dist/core/apiClient.cjs.map +1 -1
  63. package/dist/core/apiClient.d.ts +5 -9
  64. package/dist/core/apiClient.js +19 -19
  65. package/dist/core/apiClient.js.map +1 -1
  66. package/dist/core/client.cjs +7 -7
  67. package/dist/core/client.cjs.map +1 -1
  68. package/dist/core/client.d.ts +6 -9
  69. package/dist/core/client.js +7 -7
  70. package/dist/core/client.js.map +1 -1
  71. package/dist/core/core.test.d.ts +1 -0
  72. package/dist/core/generics.cjs +11 -9
  73. package/dist/core/generics.cjs.map +1 -1
  74. package/dist/core/generics.d.ts +9 -13
  75. package/dist/core/generics.js +22 -29
  76. package/dist/core/generics.js.map +1 -1
  77. package/dist/core/tests/apiClient.test.d.ts +1 -0
  78. package/dist/core/tests/client.test.d.ts +1 -0
  79. package/dist/core/tests/generics.test.d.ts +1 -0
  80. package/dist/core.cjs +114 -48
  81. package/dist/core.cjs.map +1 -1
  82. package/dist/core.d.ts +40 -65
  83. package/dist/core.js +127 -74
  84. package/dist/core.js.map +1 -1
  85. package/dist/crypto/ecies/__tests__/base.test.d.ts +4 -0
  86. package/dist/crypto/ecies/__tests__/compatibility.test.d.ts +8 -0
  87. package/dist/crypto/ecies/__tests__/constants.test.d.ts +4 -0
  88. package/dist/crypto/ecies/__tests__/native-parity.test.d.ts +7 -0
  89. package/dist/crypto/ecies/__tests__/normalization.test.d.ts +1 -0
  90. package/dist/crypto/ecies/__tests__/test-vectors.d.ts +2 -4
  91. package/dist/crypto/ecies/base.cjs +4 -3
  92. package/dist/crypto/ecies/base.cjs.map +1 -1
  93. package/dist/crypto/ecies/base.d.ts +2 -5
  94. package/dist/crypto/ecies/base.js +12 -15
  95. package/dist/crypto/ecies/base.js.map +1 -1
  96. package/dist/crypto/ecies/browser.cjs +2 -1
  97. package/dist/crypto/ecies/browser.cjs.map +1 -1
  98. package/dist/crypto/ecies/browser.d.ts +2 -7
  99. package/dist/crypto/ecies/browser.js +2 -1
  100. package/dist/crypto/ecies/browser.js.map +1 -1
  101. package/dist/crypto/ecies/constants.d.ts +7 -9
  102. package/dist/crypto/ecies/index.d.ts +8 -1
  103. package/dist/crypto/ecies/interface.cjs +4 -5
  104. package/dist/crypto/ecies/interface.cjs.map +1 -1
  105. package/dist/crypto/ecies/interface.d.ts +9 -11
  106. package/dist/crypto/ecies/interface.js +4 -5
  107. package/dist/crypto/ecies/interface.js.map +1 -1
  108. package/dist/crypto/ecies/node.cjs +3 -2
  109. package/dist/crypto/ecies/node.cjs.map +1 -1
  110. package/dist/crypto/ecies/node.d.ts +2 -7
  111. package/dist/crypto/ecies/node.js +11 -16
  112. package/dist/crypto/ecies/node.js.map +1 -1
  113. package/dist/crypto/ecies/test-vectors/eccrypto-vectors.json +72 -0
  114. package/dist/crypto/ecies/utils.cjs +2 -41
  115. package/dist/crypto/ecies/utils.cjs.map +1 -1
  116. package/dist/crypto/ecies/utils.d.ts +3 -40
  117. package/dist/crypto/ecies/utils.js +1 -35
  118. package/dist/crypto/ecies/utils.js.map +1 -1
  119. package/dist/crypto/services/WalletKeyEncryptionService.cjs +2 -2
  120. package/dist/crypto/services/WalletKeyEncryptionService.cjs.map +1 -1
  121. package/dist/crypto/services/WalletKeyEncryptionService.d.ts +3 -7
  122. package/dist/crypto/services/WalletKeyEncryptionService.js +5 -9
  123. package/dist/crypto/services/WalletKeyEncryptionService.js.map +1 -1
  124. package/dist/crypto/services/WalletKeyEncryptionService.test.d.ts +1 -0
  125. package/dist/diagnostics.d.ts +1 -3
  126. package/dist/diagnostics.test.d.ts +1 -0
  127. package/dist/errors.cjs +16 -0
  128. package/dist/errors.cjs.map +1 -1
  129. package/dist/errors.d.ts +53 -15
  130. package/dist/errors.js +18 -6
  131. package/dist/errors.js.map +1 -1
  132. package/dist/generated/abi/ComputeEngineImplementation.d.ts +2 -3
  133. package/dist/generated/abi/ComputeInstructionRegistryImplementation.d.ts +2 -3
  134. package/dist/generated/abi/DATFactoryImplementation.d.ts +2 -3
  135. package/dist/generated/abi/DATImplementation.d.ts +2 -3
  136. package/dist/generated/abi/DATPausableImplementation.d.ts +2 -3
  137. package/dist/generated/abi/DATVotesImplementation.d.ts +2 -3
  138. package/dist/generated/abi/DLPPerformanceImplementation.d.ts +2 -3
  139. package/dist/generated/abi/DLPRegistryImplementation.d.ts +2 -3
  140. package/dist/generated/abi/DLPRegistryTreasuryImplementation.d.ts +2 -3
  141. package/dist/generated/abi/DLPRewardDeployerImplementation.d.ts +2 -3
  142. package/dist/generated/abi/DLPRewardDeployerTreasuryImplementation.d.ts +2 -3
  143. package/dist/generated/abi/DLPRewardSwapImplementation.d.ts +2 -3
  144. package/dist/generated/abi/DLPRootImplementation.d.ts +1 -3
  145. package/dist/generated/abi/DLPTreasuryImplementation.d.ts +2 -3
  146. package/dist/generated/abi/DataLiquidityPoolImplementation.d.ts +1 -3
  147. package/dist/generated/abi/DataPortabilityGranteesImplementation.d.ts +2 -3
  148. package/dist/generated/abi/DataPortabilityPermissionsImplementation.d.ts +2 -3
  149. package/dist/generated/abi/DataPortabilityServersImplementation.d.ts +2 -3
  150. package/dist/generated/abi/DataRefinerRegistryImplementation.d.ts +2 -3
  151. package/dist/generated/abi/DataRegistryImplementation.cjs +13 -0
  152. package/dist/generated/abi/DataRegistryImplementation.cjs.map +1 -1
  153. package/dist/generated/abi/DataRegistryImplementation.d.ts +12 -3
  154. package/dist/generated/abi/DataRegistryImplementation.js +13 -0
  155. package/dist/generated/abi/DataRegistryImplementation.js.map +1 -1
  156. package/dist/generated/abi/QueryEngineImplementation.d.ts +2 -3
  157. package/dist/generated/abi/SwapHelperImplementation.d.ts +2 -3
  158. package/dist/generated/abi/TeePoolDedicatedGpuImplementation.d.ts +2 -3
  159. package/dist/generated/abi/TeePoolDedicatedStandardImplementation.d.ts +2 -3
  160. package/dist/generated/abi/TeePoolEphemeralStandardImplementation.d.ts +2 -3
  161. package/dist/generated/abi/TeePoolImplementation.d.ts +2 -3
  162. package/dist/generated/abi/TeePoolPersistentGpuImplementation.d.ts +2 -3
  163. package/dist/generated/abi/TeePoolPersistentStandardImplementation.d.ts +2 -3
  164. package/dist/generated/abi/TeePoolPhalaImplementation.d.ts +2 -3
  165. package/dist/generated/abi/VanaEpochImplementation.d.ts +2 -3
  166. package/dist/generated/abi/VanaPoolEntityImplementation.d.ts +2 -3
  167. package/dist/generated/abi/VanaPoolStakingImplementation.d.ts +2 -3
  168. package/dist/generated/abi/VanaPoolTreasuryImplementation.d.ts +2 -3
  169. package/dist/generated/abi/index.cjs +42 -0
  170. package/dist/generated/abi/index.cjs.map +1 -1
  171. package/dist/generated/abi/index.d.ts +47 -18
  172. package/dist/generated/abi/index.js +21 -0
  173. package/dist/generated/abi/index.js.map +1 -1
  174. package/dist/generated/event-types.cjs +17 -0
  175. package/dist/generated/event-types.cjs.map +1 -0
  176. package/dist/generated/event-types.d.ts +854 -0
  177. package/dist/generated/event-types.js +1 -0
  178. package/dist/generated/event-types.js.map +1 -0
  179. package/dist/generated/eventRegistry.cjs +3351 -0
  180. package/dist/generated/eventRegistry.cjs.map +1 -0
  181. package/dist/generated/eventRegistry.d.ts +14 -0
  182. package/dist/generated/eventRegistry.js +3326 -0
  183. package/dist/generated/eventRegistry.js.map +1 -0
  184. package/dist/generated/server/server-exports.d.ts +19 -21
  185. package/dist/generated/server/server.cjs.map +1 -1
  186. package/dist/generated/server/server.d.ts +113 -87
  187. package/dist/generated/subgraph.d.ts +329 -332
  188. package/dist/index.browser.d.ts +48 -73
  189. package/dist/index.browser.js +12 -0
  190. package/dist/index.browser.js.map +1 -1
  191. package/dist/index.cjs +3 -1
  192. package/dist/index.cjs.map +1 -1
  193. package/dist/index.d.ts +0 -2
  194. package/dist/index.js +3 -1
  195. package/dist/index.js.map +1 -1
  196. package/dist/index.node.cjs +9 -0
  197. package/dist/index.node.cjs.map +1 -1
  198. package/dist/index.node.d.ts +181 -64
  199. package/dist/index.node.js +10 -0
  200. package/dist/index.node.js.map +1 -1
  201. package/dist/node.d.ts +4 -2
  202. package/dist/platform/browser-only.d.ts +5 -8
  203. package/dist/platform/browser-only.test.d.ts +1 -0
  204. package/dist/platform/browser-safe.d.ts +6 -9
  205. package/dist/platform/browser-safe.test.d.ts +1 -0
  206. package/dist/platform/browser.cjs +7 -6
  207. package/dist/platform/browser.cjs.map +1 -1
  208. package/dist/platform/browser.d.ts +3 -6
  209. package/dist/platform/browser.js +19 -27
  210. package/dist/platform/browser.js.map +1 -1
  211. package/dist/platform/browser.test.d.ts +1 -0
  212. package/dist/platform/index.d.ts +11 -5
  213. package/dist/platform/interface.d.ts +6 -8
  214. package/dist/platform/node.d.ts +3 -7
  215. package/dist/platform/node.js +12 -19
  216. package/dist/platform/node.js.map +1 -1
  217. package/dist/platform/ports/openpgp-port.cjs +74 -0
  218. package/dist/platform/ports/openpgp-port.cjs.map +1 -0
  219. package/dist/platform/ports/openpgp-port.d.ts +13 -0
  220. package/dist/platform/ports/openpgp-port.js +59 -0
  221. package/dist/platform/ports/openpgp-port.js.map +1 -0
  222. package/dist/platform/ports/pgp-port.cjs +17 -0
  223. package/dist/platform/ports/pgp-port.cjs.map +1 -0
  224. package/dist/platform/ports/pgp-port.d.ts +35 -0
  225. package/dist/platform/ports/pgp-port.js +1 -0
  226. package/dist/platform/ports/pgp-port.js.map +1 -0
  227. package/dist/platform/shared/error-utils.d.ts +2 -4
  228. package/dist/platform/shared/pgp-utils.cjs +2 -2
  229. package/dist/platform/shared/pgp-utils.cjs.map +1 -1
  230. package/dist/platform/shared/pgp-utils.d.ts +3 -5
  231. package/dist/platform/shared/pgp-utils.js +2 -2
  232. package/dist/platform/shared/pgp-utils.js.map +1 -1
  233. package/dist/platform/shared/stream-utils.d.ts +1 -3
  234. package/dist/platform/utils.d.ts +6 -10
  235. package/dist/platform/utils.test.d.ts +1 -0
  236. package/dist/platform.browser.d.ts +9 -4
  237. package/dist/platform.d.ts +11 -5
  238. package/dist/platform.node.d.ts +10 -5
  239. package/dist/schemas/dataSchema.schema.json +53 -0
  240. package/dist/schemas/grantFile.schema.json +43 -0
  241. package/dist/server/handler.cjs.map +1 -1
  242. package/dist/server/handler.d.ts +8 -203
  243. package/dist/server/handler.js.map +1 -1
  244. package/dist/storage/index.d.ts +56 -10
  245. package/dist/storage/manager.cjs +6 -6
  246. package/dist/storage/manager.cjs.map +1 -1
  247. package/dist/storage/manager.d.ts +2 -5
  248. package/dist/storage/manager.js +5 -12
  249. package/dist/storage/manager.js.map +1 -1
  250. package/dist/storage/providers/callback-storage.cjs +3 -3
  251. package/dist/storage/providers/callback-storage.cjs.map +1 -1
  252. package/dist/storage/providers/callback-storage.d.ts +3 -9
  253. package/dist/storage/providers/callback-storage.js +3 -3
  254. package/dist/storage/providers/callback-storage.js.map +1 -1
  255. package/dist/storage/providers/google-drive.cjs +2 -2
  256. package/dist/storage/providers/google-drive.cjs.map +1 -1
  257. package/dist/storage/providers/google-drive.d.ts +3 -7
  258. package/dist/storage/providers/google-drive.js +4 -7
  259. package/dist/storage/providers/google-drive.js.map +1 -1
  260. package/dist/storage/providers/google-drive.test.d.ts +1 -0
  261. package/dist/storage/providers/ipfs.cjs +5 -5
  262. package/dist/storage/providers/ipfs.cjs.map +1 -1
  263. package/dist/storage/providers/ipfs.d.ts +3 -6
  264. package/dist/storage/providers/ipfs.js +7 -10
  265. package/dist/storage/providers/ipfs.js.map +1 -1
  266. package/dist/storage/providers/pinata.cjs +6 -6
  267. package/dist/storage/providers/pinata.cjs.map +1 -1
  268. package/dist/storage/providers/pinata.d.ts +5 -8
  269. package/dist/storage/providers/pinata.js +8 -11
  270. package/dist/storage/providers/pinata.js.map +1 -1
  271. package/dist/storage/tests/callbackStorage.test.d.ts +1 -0
  272. package/dist/storage/tests/googleDriveStorage.test.d.ts +1 -0
  273. package/dist/storage/tests/ipfsStorage.test.d.ts +1 -0
  274. package/dist/storage/tests/pinataStorage.test.d.ts +1 -0
  275. package/dist/storage/tests/storageManager.test.d.ts +1 -0
  276. package/dist/tests/abi.test.d.ts +1 -0
  277. package/dist/tests/chains-definitions.test.d.ts +1 -0
  278. package/dist/tests/core-encryption.test.d.ts +1 -0
  279. package/dist/tests/core-extended.test.d.ts +1 -0
  280. package/dist/tests/core-generics-coverage.test.d.ts +1 -0
  281. package/dist/tests/coverage-boost.test.d.ts +1 -0
  282. package/dist/tests/crypto-cross-platform-compatibility.test.d.ts +1 -0
  283. package/dist/tests/data-addfile-permissions-schema.test.d.ts +1 -0
  284. package/dist/tests/data-additional-methods.test.d.ts +1 -0
  285. package/dist/tests/data-controller-edge-cases.test.d.ts +1 -0
  286. package/dist/tests/data-ipfs-gateways.test.d.ts +1 -0
  287. package/dist/tests/data-relayer.test.d.ts +1 -0
  288. package/dist/tests/data-schema-validation.test.d.ts +1 -0
  289. package/dist/tests/data-simple-methods.test.d.ts +1 -0
  290. package/dist/tests/data.test.d.ts +1 -0
  291. package/dist/tests/demo-integration.test.d.ts +1 -0
  292. package/dist/tests/demo-trusted-server-integration.test.d.ts +1 -0
  293. package/dist/tests/download-relayer.test.d.ts +1 -0
  294. package/dist/tests/dual-mode-permissions.test.d.ts +1 -0
  295. package/dist/tests/dual-mode-trusted-servers.test.d.ts +1 -0
  296. package/dist/tests/encryption-correct-implementation.test.d.ts +1 -0
  297. package/dist/tests/encryption-coverage.test.d.ts +1 -0
  298. package/dist/tests/encryption-edge-cases.test.d.ts +1 -0
  299. package/dist/tests/encryption-utils-updated.test.d.ts +1 -0
  300. package/dist/tests/errors-coverage.test.d.ts +1 -0
  301. package/dist/tests/errors.test.d.ts +1 -0
  302. package/dist/tests/factories/mockFactory.d.ts +316 -0
  303. package/dist/tests/fakes/FakeStorageManager.d.ts +200 -0
  304. package/dist/tests/fakes/FakeStorageManager.test.d.ts +1 -0
  305. package/dist/tests/fakes/FakeWaitForTransactionEvents.d.ts +170 -0
  306. package/dist/tests/fakes/FakeWaitForTransactionEvents.test.d.ts +1 -0
  307. package/dist/tests/fakes/fake-pgp-port.d.ts +13 -0
  308. package/dist/tests/grantValidation-edge-cases.test.d.ts +1 -0
  309. package/dist/tests/grantValidation-unreachable-branch.test.d.ts +1 -0
  310. package/dist/tests/helper-methods.test.d.ts +1 -0
  311. package/dist/tests/helpers/platformTestHelpers.d.ts +106 -0
  312. package/dist/tests/helpers/typedMocks.d.ts +64 -0
  313. package/dist/tests/index-browser.test.d.ts +1 -0
  314. package/dist/tests/index-node.test.d.ts +1 -0
  315. package/dist/tests/index.test.d.ts +1 -0
  316. package/dist/tests/mocks/platformAdapter.d.ts +12 -0
  317. package/dist/tests/new-permissions-methods.test.d.ts +1 -0
  318. package/dist/tests/no-buffer-browser.test.d.ts +1 -0
  319. package/dist/tests/permissions-grantee.test.d.ts +1 -0
  320. package/dist/tests/permissions-schema-validation.test.d.ts +1 -0
  321. package/dist/tests/permissions-server-files.test.d.ts +1 -0
  322. package/dist/tests/permissions-transaction-options.test.d.ts +1 -0
  323. package/dist/tests/permissions-trust-servers.test.d.ts +1 -0
  324. package/dist/tests/permissions.test.d.ts +1 -0
  325. package/dist/tests/personal.test.d.ts +1 -0
  326. package/dist/tests/platform-browser.test.d.ts +1 -0
  327. package/dist/tests/platform-crypto-expanded.test.d.ts +1 -0
  328. package/dist/tests/platform-crypto.test.d.ts +1 -0
  329. package/dist/tests/platform-index.test.d.ts +1 -0
  330. package/dist/tests/platform-node.test.d.ts +1 -0
  331. package/dist/tests/platform-shared-utils.test.d.ts +1 -0
  332. package/dist/tests/platform-updated.test.d.ts +1 -0
  333. package/dist/tests/protocol-additional-methods.test.d.ts +1 -0
  334. package/dist/tests/protocol.test.d.ts +1 -0
  335. package/dist/tests/read-only-mode.test.d.ts +1 -0
  336. package/dist/tests/schemas.test.d.ts +1 -0
  337. package/dist/tests/server-handler.test.d.ts +1 -0
  338. package/dist/tests/setup.d.ts +7 -0
  339. package/dist/tests/signatureFormatter.test.d.ts +1 -0
  340. package/dist/tests/trusted-server-queries.test.d.ts +1 -0
  341. package/dist/tests/typedDataConverter.test.d.ts +1 -0
  342. package/dist/tests/types-contracts.test.d.ts +1 -0
  343. package/dist/tests/types-data.test.d.ts +1 -0
  344. package/dist/tests/types-external-apis.test.d.ts +1 -0
  345. package/dist/tests/types-generics.test.d.ts +1 -0
  346. package/dist/tests/types-permissions.test.d.ts +1 -0
  347. package/dist/tests/types-upload-params.test.d.ts +1 -0
  348. package/dist/tests/types.test.d.ts +1 -0
  349. package/dist/tests/utils-formatters.test.d.ts +1 -0
  350. package/dist/tests/utils-grantFiles-edge-cases.test.d.ts +1 -0
  351. package/dist/tests/utils-grantFiles-validation.test.d.ts +1 -0
  352. package/dist/tests/utils-grantFiles.test.d.ts +1 -0
  353. package/dist/tests/utils-grantValidation-consolidated.test.d.ts +1 -0
  354. package/dist/tests/utils-grants.test.d.ts +1 -0
  355. package/dist/tests/utils-ipfs-additional.test.d.ts +1 -0
  356. package/dist/tests/utils-ipfs.test.d.ts +4 -0
  357. package/dist/tests/utils-schemaValidation.test.d.ts +1 -0
  358. package/dist/tests/vana.test.d.ts +1 -0
  359. package/dist/tests/wallet-crypto-compatibility.test.d.ts +1 -0
  360. package/dist/types/blockchain.cjs +17 -0
  361. package/dist/types/blockchain.cjs.map +1 -0
  362. package/dist/types/blockchain.d.ts +57 -0
  363. package/dist/types/blockchain.js +1 -0
  364. package/dist/types/blockchain.js.map +1 -0
  365. package/dist/types/chains-additional.test.d.ts +1 -0
  366. package/dist/types/chains.d.ts +6 -9
  367. package/dist/types/config.cjs +10 -0
  368. package/dist/types/config.cjs.map +1 -1
  369. package/dist/types/config.d.ts +161 -54
  370. package/dist/types/config.js +8 -0
  371. package/dist/types/config.js.map +1 -1
  372. package/dist/types/contracts.cjs.map +1 -1
  373. package/dist/types/contracts.d.ts +8 -11
  374. package/dist/types/controller-context.cjs +17 -0
  375. package/dist/types/controller-context.cjs.map +1 -0
  376. package/dist/types/controller-context.d.ts +64 -0
  377. package/dist/types/controller-context.js +1 -0
  378. package/dist/types/controller-context.js.map +1 -0
  379. package/dist/types/data.cjs.map +1 -1
  380. package/dist/types/data.d.ts +107 -39
  381. package/dist/types/external-apis.d.ts +10 -12
  382. package/dist/types/generics.d.ts +35 -38
  383. package/dist/types/index.cjs +5 -4
  384. package/dist/types/index.cjs.map +1 -1
  385. package/dist/types/index.d.ts +20 -34
  386. package/dist/types/index.js +9 -2
  387. package/dist/types/index.js.map +1 -1
  388. package/dist/types/operations.cjs +2 -2
  389. package/dist/types/operations.cjs.map +1 -1
  390. package/dist/types/operations.d.ts +32 -28
  391. package/dist/types/operations.js +2 -2
  392. package/dist/types/operations.js.map +1 -1
  393. package/dist/types/permissions.d.ts +55 -58
  394. package/dist/types/personal.cjs.map +1 -1
  395. package/dist/types/personal.d.ts +6 -8
  396. package/dist/types/relayer.d.ts +15 -18
  397. package/dist/types/storage.d.ts +6 -8
  398. package/dist/types/storage.js +2 -5
  399. package/dist/types/storage.js.map +1 -1
  400. package/dist/types/transactionResults.cjs.map +1 -1
  401. package/dist/types/transactionResults.d.ts +193 -25
  402. package/dist/types/utils.cjs.map +1 -1
  403. package/dist/types/utils.d.ts +26 -25
  404. package/dist/types.d.ts +4 -40
  405. package/dist/utils/__tests__/parseTransaction.test.d.ts +1 -0
  406. package/dist/utils/__tests__/pojo-serialization.test.d.ts +1 -0
  407. package/dist/utils/__tests__/signatureCache.test.d.ts +1 -0
  408. package/dist/utils/__tests__/transaction-edge-cases.test.d.ts +1 -0
  409. package/dist/utils/__tests__/transactionHelpers.test.d.ts +1 -0
  410. package/dist/utils/__tests__/urlResolver.test.d.ts +4 -0
  411. package/dist/utils/blockchain/registry.cjs +2 -2
  412. package/dist/utils/blockchain/registry.cjs.map +1 -1
  413. package/dist/utils/blockchain/registry.d.ts +6 -8
  414. package/dist/utils/blockchain/registry.js +2 -2
  415. package/dist/utils/blockchain/registry.js.map +1 -1
  416. package/dist/utils/blockchain/registry.test.d.ts +1 -0
  417. package/dist/utils/crypto-utils.cjs +0 -12
  418. package/dist/utils/crypto-utils.cjs.map +1 -1
  419. package/dist/utils/crypto-utils.d.ts +9 -27
  420. package/dist/utils/crypto-utils.js +0 -11
  421. package/dist/utils/crypto-utils.js.map +1 -1
  422. package/dist/utils/crypto-utils.test.d.ts +1 -0
  423. package/dist/utils/download.cjs +3 -3
  424. package/dist/utils/download.cjs.map +1 -1
  425. package/dist/utils/download.d.ts +13 -14
  426. package/dist/utils/download.js +2 -2
  427. package/dist/utils/download.js.map +1 -1
  428. package/dist/utils/encoding.cjs +1 -1
  429. package/dist/utils/encoding.cjs.map +1 -1
  430. package/dist/utils/encoding.d.ts +4 -6
  431. package/dist/utils/encoding.js +1 -1
  432. package/dist/utils/encoding.js.map +1 -1
  433. package/dist/utils/encoding.test.d.ts +1 -0
  434. package/dist/utils/encryption.cjs +16 -10
  435. package/dist/utils/encryption.cjs.map +1 -1
  436. package/dist/utils/encryption.d.ts +13 -17
  437. package/dist/utils/encryption.js +16 -10
  438. package/dist/utils/encryption.js.map +1 -1
  439. package/dist/utils/formatters.cjs +4 -2
  440. package/dist/utils/formatters.cjs.map +1 -1
  441. package/dist/utils/formatters.d.ts +4 -6
  442. package/dist/utils/formatters.js +4 -2
  443. package/dist/utils/formatters.js.map +1 -1
  444. package/dist/utils/grantFiles.cjs +7 -4
  445. package/dist/utils/grantFiles.cjs.map +1 -1
  446. package/dist/utils/grantFiles.d.ts +6 -10
  447. package/dist/utils/grantFiles.js +7 -4
  448. package/dist/utils/grantFiles.js.map +1 -1
  449. package/dist/utils/grantValidation.cjs +1 -1
  450. package/dist/utils/grantValidation.cjs.map +1 -1
  451. package/dist/utils/grantValidation.d.ts +14 -17
  452. package/dist/utils/grantValidation.js +1 -1
  453. package/dist/utils/grantValidation.js.map +1 -1
  454. package/dist/utils/grants.cjs +1 -1
  455. package/dist/utils/grants.cjs.map +1 -1
  456. package/dist/utils/grants.d.ts +10 -13
  457. package/dist/utils/grants.js +1 -1
  458. package/dist/utils/grants.js.map +1 -1
  459. package/dist/utils/ipfs.d.ts +8 -10
  460. package/dist/utils/lazy-import.cjs +4 -6
  461. package/dist/utils/lazy-import.cjs.map +1 -1
  462. package/dist/utils/lazy-import.d.ts +1 -3
  463. package/dist/utils/lazy-import.js +4 -6
  464. package/dist/utils/lazy-import.js.map +1 -1
  465. package/dist/utils/multicall.cjs +4 -2
  466. package/dist/utils/multicall.cjs.map +1 -1
  467. package/dist/utils/multicall.d.ts +5 -8
  468. package/dist/utils/multicall.js +4 -2
  469. package/dist/utils/multicall.js.map +1 -1
  470. package/dist/utils/parseTransactionPojo.cjs +87 -0
  471. package/dist/utils/parseTransactionPojo.cjs.map +1 -0
  472. package/dist/utils/parseTransactionPojo.d.ts +31 -0
  473. package/dist/utils/parseTransactionPojo.js +63 -0
  474. package/dist/utils/parseTransactionPojo.js.map +1 -0
  475. package/dist/utils/schemaValidation.cjs +5 -5
  476. package/dist/utils/schemaValidation.cjs.map +1 -1
  477. package/dist/utils/schemaValidation.d.ts +8 -12
  478. package/dist/utils/schemaValidation.js +7 -10
  479. package/dist/utils/schemaValidation.js.map +1 -1
  480. package/dist/utils/signatureCache.cjs +1 -2
  481. package/dist/utils/signatureCache.cjs.map +1 -1
  482. package/dist/utils/signatureCache.d.ts +4 -7
  483. package/dist/utils/signatureCache.js +4 -8
  484. package/dist/utils/signatureCache.js.map +1 -1
  485. package/dist/utils/signatureFormatter.cjs +6 -9
  486. package/dist/utils/signatureFormatter.cjs.map +1 -1
  487. package/dist/utils/signatureFormatter.d.ts +2 -5
  488. package/dist/utils/signatureFormatter.js +6 -9
  489. package/dist/utils/signatureFormatter.js.map +1 -1
  490. package/dist/utils/tests/multicall.test.d.ts +1 -0
  491. package/dist/utils/transactionHelpers.cjs +54 -0
  492. package/dist/utils/transactionHelpers.cjs.map +1 -0
  493. package/dist/utils/transactionHelpers.d.ts +80 -0
  494. package/dist/utils/transactionHelpers.js +29 -0
  495. package/dist/utils/transactionHelpers.js.map +1 -0
  496. package/dist/utils/typeGuards.cjs +109 -0
  497. package/dist/utils/typeGuards.cjs.map +1 -0
  498. package/dist/utils/typeGuards.d.ts +138 -0
  499. package/dist/utils/typeGuards.js +74 -0
  500. package/dist/utils/typeGuards.js.map +1 -0
  501. package/dist/utils/typedDataConverter.d.ts +3 -6
  502. package/dist/utils/urlResolver.cjs +1 -1
  503. package/dist/utils/urlResolver.cjs.map +1 -1
  504. package/dist/utils/urlResolver.d.ts +2 -4
  505. package/dist/utils/urlResolver.js +2 -2
  506. package/dist/utils/urlResolver.js.map +1 -1
  507. package/dist/utils/wallet.cjs +62 -0
  508. package/dist/utils/wallet.cjs.map +1 -0
  509. package/dist/utils/wallet.d.ts +32 -0
  510. package/dist/utils/wallet.js +36 -0
  511. package/dist/utils/wallet.js.map +1 -0
  512. package/dist/{chains.browser.cjs → utils/withEvents.cjs} +22 -15
  513. package/dist/utils/withEvents.cjs.map +1 -0
  514. package/dist/utils/withEvents.d.ts +56 -0
  515. package/dist/utils/withEvents.js +18 -0
  516. package/dist/utils/withEvents.js.map +1 -0
  517. package/package.json +23 -13
  518. package/dist/browser.d.cts +0 -2
  519. package/dist/chains/definitions.d.cts +0 -53
  520. package/dist/chains/index.d.cts +0 -2
  521. package/dist/chains.browser.cjs.map +0 -1
  522. package/dist/chains.browser.d.cts +0 -2
  523. package/dist/chains.d.cts +0 -2
  524. package/dist/chains.node.d.cts +0 -2
  525. package/dist/config/addresses.d.cts +0 -380
  526. package/dist/config/chains.d.cts +0 -85
  527. package/dist/config/eventMappings.cjs +0 -114
  528. package/dist/config/eventMappings.cjs.map +0 -1
  529. package/dist/config/eventMappings.d.cts +0 -108
  530. package/dist/config/eventMappings.d.ts +0 -108
  531. package/dist/config/eventMappings.js +0 -90
  532. package/dist/config/eventMappings.js.map +0 -1
  533. package/dist/config/features.d.cts +0 -64
  534. package/dist/contracts/contractController.d.cts +0 -96
  535. package/dist/controllers/data.d.cts +0 -941
  536. package/dist/controllers/permissions.d.cts +0 -25
  537. package/dist/controllers/protocol.d.cts +0 -167
  538. package/dist/controllers/schemas.d.cts +0 -272
  539. package/dist/controllers/server.d.cts +0 -243
  540. package/dist/core/apiClient.d.cts +0 -165
  541. package/dist/core/client.d.cts +0 -92
  542. package/dist/core/generics.d.cts +0 -120
  543. package/dist/core.d.cts +0 -466
  544. package/dist/crypto/ecies/__tests__/test-vectors.d.cts +0 -40
  545. package/dist/crypto/ecies/base.d.cts +0 -143
  546. package/dist/crypto/ecies/browser.d.cts +0 -48
  547. package/dist/crypto/ecies/constants.d.cts +0 -122
  548. package/dist/crypto/ecies/index.d.cts +0 -1
  549. package/dist/crypto/ecies/interface.d.cts +0 -176
  550. package/dist/crypto/ecies/node.d.cts +0 -50
  551. package/dist/crypto/ecies/utils.d.cts +0 -67
  552. package/dist/crypto/services/WalletKeyEncryptionService.d.cts +0 -92
  553. package/dist/diagnostics.d.cts +0 -26
  554. package/dist/errors.d.cts +0 -350
  555. package/dist/generated/abi/ComputeEngineImplementation.d.cts +0 -996
  556. package/dist/generated/abi/ComputeInstructionRegistryImplementation.d.cts +0 -545
  557. package/dist/generated/abi/DATFactoryImplementation.d.cts +0 -661
  558. package/dist/generated/abi/DATImplementation.d.cts +0 -693
  559. package/dist/generated/abi/DATPausableImplementation.d.cts +0 -1145
  560. package/dist/generated/abi/DATVotesImplementation.d.cts +0 -1095
  561. package/dist/generated/abi/DLPPerformanceImplementation.d.cts +0 -883
  562. package/dist/generated/abi/DLPRegistryImplementation.d.cts +0 -1123
  563. package/dist/generated/abi/DLPRegistryTreasuryImplementation.d.cts +0 -452
  564. package/dist/generated/abi/DLPRewardDeployerImplementation.d.cts +0 -714
  565. package/dist/generated/abi/DLPRewardDeployerTreasuryImplementation.d.cts +0 -452
  566. package/dist/generated/abi/DLPRewardSwapImplementation.d.cts +0 -706
  567. package/dist/generated/abi/DLPRootImplementation.d.cts +0 -1248
  568. package/dist/generated/abi/DLPTreasuryImplementation.d.cts +0 -452
  569. package/dist/generated/abi/DataLiquidityPoolImplementation.d.cts +0 -737
  570. package/dist/generated/abi/DataPortabilityGranteesImplementation.d.cts +0 -661
  571. package/dist/generated/abi/DataPortabilityPermissionsImplementation.d.cts +0 -989
  572. package/dist/generated/abi/DataPortabilityServersImplementation.d.cts +0 -1086
  573. package/dist/generated/abi/DataRefinerRegistryImplementation.d.cts +0 -737
  574. package/dist/generated/abi/DataRegistryImplementation.d.cts +0 -1004
  575. package/dist/generated/abi/QueryEngineImplementation.d.cts +0 -1001
  576. package/dist/generated/abi/SwapHelperImplementation.d.cts +0 -764
  577. package/dist/generated/abi/TeePoolDedicatedGpuImplementation.d.cts +0 -701
  578. package/dist/generated/abi/TeePoolDedicatedStandardImplementation.d.cts +0 -701
  579. package/dist/generated/abi/TeePoolEphemeralStandardImplementation.d.cts +0 -701
  580. package/dist/generated/abi/TeePoolImplementation.d.cts +0 -993
  581. package/dist/generated/abi/TeePoolPersistentGpuImplementation.d.cts +0 -701
  582. package/dist/generated/abi/TeePoolPersistentStandardImplementation.d.cts +0 -701
  583. package/dist/generated/abi/TeePoolPhalaImplementation.d.cts +0 -993
  584. package/dist/generated/abi/VanaEpochImplementation.d.cts +0 -900
  585. package/dist/generated/abi/VanaPoolEntityImplementation.d.cts +0 -934
  586. package/dist/generated/abi/VanaPoolStakingImplementation.d.cts +0 -693
  587. package/dist/generated/abi/VanaPoolTreasuryImplementation.d.cts +0 -394
  588. package/dist/generated/abi/index.d.cts +0 -26516
  589. package/dist/generated/server/server-exports.d.cts +0 -21
  590. package/dist/generated/server/server.d.cts +0 -512
  591. package/dist/generated/subgraph.d.cts +0 -5981
  592. package/dist/index.browser.cjs +0 -151
  593. package/dist/index.browser.cjs.map +0 -1
  594. package/dist/index.browser.d.cts +0 -177
  595. package/dist/index.d.cts +0 -2
  596. package/dist/index.node.d.cts +0 -64
  597. package/dist/node.d.cts +0 -2
  598. package/dist/permissions-DNKPu_G0.d.cts +0 -1666
  599. package/dist/permissions-eo8YeLGf.d.ts +0 -1666
  600. package/dist/platform/browser-only.d.cts +0 -25
  601. package/dist/platform/browser-safe.d.cts +0 -32
  602. package/dist/platform/browser.d.cts +0 -74
  603. package/dist/platform/index.d.cts +0 -5
  604. package/dist/platform/interface.d.cts +0 -218
  605. package/dist/platform/node.d.cts +0 -27
  606. package/dist/platform/shared/error-utils.d.cts +0 -25
  607. package/dist/platform/shared/pgp-utils.d.cts +0 -61
  608. package/dist/platform/shared/stream-utils.d.cts +0 -16
  609. package/dist/platform/utils.d.cts +0 -53
  610. package/dist/platform.browser.cjs +0 -41
  611. package/dist/platform.browser.cjs.map +0 -1
  612. package/dist/platform.browser.d.cts +0 -4
  613. package/dist/platform.d.cts +0 -5
  614. package/dist/platform.node.d.cts +0 -5
  615. package/dist/server/handler.d.cts +0 -282
  616. package/dist/storage/index.d.cts +0 -10
  617. package/dist/storage/manager.d.cts +0 -150
  618. package/dist/storage/providers/callback-storage.d.cts +0 -100
  619. package/dist/storage/providers/google-drive.d.cts +0 -156
  620. package/dist/storage/providers/ipfs.d.cts +0 -163
  621. package/dist/storage/providers/pinata.d.cts +0 -173
  622. package/dist/types/chains.d.cts +0 -34
  623. package/dist/types/config.d.cts +0 -726
  624. package/dist/types/contracts.d.cts +0 -68
  625. package/dist/types/data.d.cts +0 -694
  626. package/dist/types/eccrypto-js.d.d.cts +0 -13
  627. package/dist/types/eccrypto-js.d.d.ts +0 -13
  628. package/dist/types/external-apis.d.cts +0 -186
  629. package/dist/types/generics.d.cts +0 -450
  630. package/dist/types/index.d.cts +0 -34
  631. package/dist/types/operations.d.cts +0 -108
  632. package/dist/types/permissions.d.cts +0 -957
  633. package/dist/types/personal.d.cts +0 -40
  634. package/dist/types/relayer.d.cts +0 -284
  635. package/dist/types/storage.d.cts +0 -131
  636. package/dist/types/transactionResults.d.cts +0 -25
  637. package/dist/types/utils.d.cts +0 -819
  638. package/dist/types.d.cts +0 -66
  639. package/dist/utils/blockchain/registry.d.cts +0 -34
  640. package/dist/utils/crypto-utils.d.cts +0 -118
  641. package/dist/utils/download.d.cts +0 -41
  642. package/dist/utils/encoding.d.cts +0 -54
  643. package/dist/utils/encryption.d.cts +0 -275
  644. package/dist/utils/eventParsing.cjs +0 -111
  645. package/dist/utils/eventParsing.cjs.map +0 -1
  646. package/dist/utils/eventParsing.d.cts +0 -60
  647. package/dist/utils/eventParsing.d.ts +0 -60
  648. package/dist/utils/eventParsing.js +0 -86
  649. package/dist/utils/eventParsing.js.map +0 -1
  650. package/dist/utils/formatters.d.cts +0 -120
  651. package/dist/utils/grantFiles.d.cts +0 -186
  652. package/dist/utils/grantValidation.d.cts +0 -150
  653. package/dist/utils/grants.d.cts +0 -70
  654. package/dist/utils/ipfs.d.cts +0 -90
  655. package/dist/utils/lazy-import.d.cts +0 -20
  656. package/dist/utils/multicall.d.cts +0 -129
  657. package/dist/utils/schemaValidation.d.cts +0 -172
  658. package/dist/utils/signatureCache.d.cts +0 -134
  659. package/dist/utils/signatureFormatter.d.cts +0 -39
  660. package/dist/utils/transactionParsing.cjs +0 -84
  661. package/dist/utils/transactionParsing.cjs.map +0 -1
  662. package/dist/utils/transactionParsing.d.cts +0 -25
  663. package/dist/utils/transactionParsing.d.ts +0 -25
  664. package/dist/utils/transactionParsing.js +0 -62
  665. package/dist/utils/transactionParsing.js.map +0 -1
  666. package/dist/utils/typedDataConverter.d.cts +0 -13
  667. package/dist/utils/urlResolver.d.cts +0 -40
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/grantFiles.ts"],"sourcesContent":["import { keccak256, toHex } from \"viem\";\nimport type { GrantFile, GrantPermissionParams } from \"../types/permissions\";\nimport { SerializationError, NetworkError } from \"../errors\";\n\ninterface GrantFileStorageResponse {\n success: boolean;\n error?: string;\n url?: string;\n}\n\n/**\n * Creates a grant file structure from permission parameters.\n *\n * @remarks\n * This function constructs the JSON structure that represents a permission grant\n * in the Vana protocol. The grant file contains all necessary information for\n * a grantee to perform operations on behalf of the grantor.\n *\n * @param params - The permission parameters to create the grant file from\n * @returns The constructed grant file object\n * @example\n * ```typescript\n * const grantFile = createGrantFile({\n * grantee: '0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36',\n * operation: 'llm_inference',\n * parameters: {\n * model: 'gpt-4',\n * maxTokens: 1000\n * },\n * expiresAt: Date.now() + 86400000 // 24 hours\n * });\n *\n * console.log(grantFile);\n * // {\n * // grantee: '0x742d...',\n * // operation: 'llm_inference',\n * // parameters: { model: 'gpt-4', maxTokens: 1000 },\n * // expires: 1234567890\n * // }\n * ```\n */\nexport function createGrantFile(params: GrantPermissionParams): GrantFile {\n const grantFile: GrantFile = {\n grantee: params.grantee,\n operation: params.operation,\n parameters: params.parameters,\n };\n\n // Add expiration if provided\n if (params.expiresAt) {\n grantFile.expires = params.expiresAt;\n }\n\n return grantFile;\n}\n\n/**\n * Stores a grant file in IPFS via the relayer service.\n *\n * @remarks\n * This function uploads the grant file to IPFS through the relayer's upload endpoint.\n * The returned URL can be stored on-chain as part of the permission grant, allowing\n * anyone to retrieve the detailed permission parameters later.\n *\n * @param grantFile - The grant file to store\n * @param relayerUrl - URL of the relayer service\n * @returns Promise resolving to the IPFS URL\n * @throws {NetworkError} When the upload fails or relayer is unavailable\n * @example\n * ```typescript\n * const grantFile = createGrantFile(params);\n *\n * try {\n * const ipfsUrl = await storeGrantFile(grantFile, 'https://relayer.vana.com');\n * console.log(`Grant file stored at: ${ipfsUrl}`);\n * // ipfsUrl: \"ipfs://QmHash123...\"\n * } catch (error) {\n * console.error('Failed to store grant file:', error);\n * }\n * ```\n */\nexport async function storeGrantFile(\n grantFile: GrantFile,\n relayerUrl: string,\n): Promise<string> {\n try {\n // Convert grant file to blob and use IPFS upload endpoint\n const grantFileBlob = new Blob([JSON.stringify(grantFile, null, 2)], {\n type: \"application/json\",\n });\n\n const formData = new FormData();\n formData.append(\"file\", grantFileBlob, \"grant-file.json\");\n\n const response = await fetch(`${relayerUrl}/api/ipfs/upload`, {\n method: \"POST\",\n body: formData,\n });\n\n if (!response.ok) {\n throw new NetworkError(\n `Failed to store grant file: ${response.statusText}`,\n new Error(`HTTP ${response.status}`),\n );\n }\n\n const responseData: unknown = await response.json();\n const data = responseData as GrantFileStorageResponse;\n\n if (!data.success) {\n throw new NetworkError(data.error || \"Failed to store grant file\");\n }\n\n return data.url || \"\"; // The IPFS URL from the upload response\n } catch (error) {\n if (error instanceof NetworkError) {\n throw error;\n }\n throw new NetworkError(\n `Network error while storing grant file: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error as Error,\n );\n }\n}\n\n/**\n * Retrieves detailed grant file data from IPFS or HTTP storage.\n *\n * @remarks\n * **This is Step 2 of the performant two-step permission API.**\n *\n * Use this method to resolve detailed permission data (operation, parameters, etc.)\n * for specific grants after first getting the fast on-chain data using\n * `getUserPermissionGrantsOnChain()`. This design eliminates N+1 query problems\n * by allowing selective lazy-loading of expensive off-chain data.\n *\n * **Performance**: Single network request per grant file (typically 100-500ms).\n * **Reliability**: Tries multiple IPFS gateways as fallbacks if primary URL fails.\n *\n * @param grantUrl - The grant file URL from OnChainPermissionGrant.grantUrl\n * @param _relayerUrl - URL of the relayer service (optional, unused)\n * @param downloadRelayer - Optional download relayer for proxying CORS-restricted downloads\n * @param downloadRelayer.proxyDownload - Function to proxy download requests through application server\n * @returns Promise resolving to the complete grant file with operation details\n * @throws {NetworkError} When all retrieval attempts fail\n * @throws {SerializationError} When grant file format is invalid\n * @example\n * ```typescript\n * // Step 1: Fast on-chain data (no N+1 queries)\n * const grants = await vana.permissions.getUserPermissionGrantsOnChain();\n *\n * // Step 2: Lazy-load details for specific grant when needed\n * const grantFile = await retrieveGrantFile(grants[0].grantUrl);\n *\n * console.log(`Operation: ${grantFile.operation}`);\n * console.log(`Grantee: ${grantFile.grantee}`);\n * console.log(`Parameters:`, grantFile.parameters);\n *\n * // Only fetch details for grants user actually wants to see\n * for (const grant of selectedGrants) {\n * const details = await retrieveGrantFile(grant.grantUrl);\n * displayGrantDetails(details);\n * }\n * ```\n */\nexport async function retrieveGrantFile(\n grantUrl: string,\n _relayerUrl?: string,\n downloadRelayer?: { proxyDownload: (url: string) => Promise<Blob> },\n): Promise<GrantFile> {\n try {\n // Check if the URL is a gateway URL instead of ipfs:// protocol\n if (grantUrl.startsWith(\"http\") && grantUrl.includes(\"/ipfs/\")) {\n console.warn(\n `⚠️ Grant URL uses HTTP gateway format instead of ipfs:// protocol. ` +\n `Found: ${grantUrl}. ` +\n `Consider using ipfs:// format for better protocol-agnostic storage.`,\n );\n }\n\n // Use the unified download utility\n const { fetchWithRelayer } = await import(\"./download\");\n const response = await fetchWithRelayer(grantUrl, downloadRelayer);\n\n if (!response.ok) {\n throw new NetworkError(\n `Failed to retrieve grant file: HTTP ${response.status}`,\n );\n }\n\n const text = await response.text();\n const grantFile = JSON.parse(text);\n\n if (!validateGrantFile(grantFile)) {\n throw new NetworkError(`Invalid grant file format from ${grantUrl}`);\n }\n\n return grantFile;\n } catch (error) {\n if (error instanceof NetworkError) {\n throw error;\n }\n throw new NetworkError(\n `Error retrieving grant file: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error as Error,\n );\n }\n}\n\n/**\n * Generates a content hash for a grant file.\n * This can be used for integrity verification.\n *\n * @remarks\n * Creates a deterministic keccak256 hash of the grant file by first sorting\n * all object keys recursively to ensure consistent hashing regardless of\n * property order. This hash can be used to verify grant file integrity\n * or as a unique identifier.\n *\n * @param grantFile - The grant file to generate a hash for\n * @returns The keccak256 hash of the grant file as a hex string\n * @throws {SerializationError} When the grant file cannot be serialized\n * @example\n * ```typescript\n * const grantFile = {\n * grantee: '0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36',\n * operation: 'read',\n * parameters: { version: '1.0', mode: 'full' }\n * };\n *\n * const hash = getGrantFileHash(grantFile);\n * console.log(`Grant file hash: ${hash}`);\n * // \"0x1234567890abcdef...\"\n *\n * // Same grant file with different property order produces same hash\n * const grantFile2 = {\n * operation: 'read',\n * parameters: { mode: 'full', version: '1.0' },\n * grantee: '0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36'\n * };\n *\n * const hash2 = getGrantFileHash(grantFile2);\n * console.log(hash === hash2); // true\n * ```\n */\nexport function getGrantFileHash(grantFile: GrantFile): string {\n try {\n // Create a stable JSON representation\n const sortedFile: GrantFile = {\n grantee: grantFile.grantee,\n operation: grantFile.operation,\n parameters: sortObjectKeys(grantFile.parameters) as Record<\n string,\n unknown\n >,\n };\n\n // Add expires if present\n if (grantFile.expires !== undefined) {\n sortedFile.expires = grantFile.expires;\n }\n\n const jsonString = JSON.stringify(sortedFile);\n console.info(`Hash: ${keccak256(toHex(jsonString))}`);\n return keccak256(toHex(jsonString));\n } catch (error) {\n throw new SerializationError(\n `Failed to generate grant file hash: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n}\n\n/**\n * Recursively sorts object keys for stable serialization.\n *\n * @param obj - The object to sort keys recursively\n * @returns The object with all keys sorted recursively\n */\nfunction sortObjectKeys(obj: unknown): unknown {\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => sortObjectKeys(item));\n }\n\n const sortedObj: Record<string, unknown> = {};\n Object.keys(obj as Record<string, unknown>)\n .sort()\n .forEach((key) => {\n sortedObj[key] = sortObjectKeys((obj as Record<string, unknown>)[key]);\n });\n\n return sortedObj;\n}\n\n/**\n * Validates that a grant file has the required structure.\n *\n * @remarks\n * Performs runtime validation to ensure data conforms to the GrantFile interface.\n * Checks for required fields (grantee, operation, parameters) and validates their\n * types and formats. This is a type guard function that enables TypeScript to\n * narrow the type when it returns true.\n *\n * @param data - The data to validate as a grant file\n * @returns True if the data is a valid grant file, false otherwise\n * @example\n * ```typescript\n * const unknownData = await fetch(url).then(r => r.json());\n *\n * if (validateGrantFile(unknownData)) {\n * // TypeScript now knows unknownData is a GrantFile\n * console.log(`Grant for operation: ${unknownData.operation}`);\n * console.log(`Grantee: ${unknownData.grantee}`);\n * } else {\n * throw new Error('Invalid grant file format');\n * }\n *\n * // Validation examples:\n * validateGrantFile({\n * grantee: '0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36',\n * operation: 'read',\n * parameters: {}\n * }); // true\n *\n * validateGrantFile({\n * grantee: 'invalid-address',\n * operation: 'read',\n * parameters: {}\n * }); // false (invalid address format)\n *\n * validateGrantFile({\n * operation: 'read',\n * parameters: {}\n * }); // false (missing grantee)\n * ```\n */\nexport function validateGrantFile(data: unknown): data is GrantFile {\n if (!data || typeof data !== \"object\") {\n return false;\n }\n\n const obj = data as Record<string, unknown>;\n\n // Validate required fields\n // Validate grantee address\n if (\n typeof obj.grantee !== \"string\" ||\n !obj.grantee.match(/^0x[a-fA-F0-9]{40}$/)\n ) {\n return false;\n }\n\n if (typeof obj.operation !== \"string\" || obj.operation.length === 0) {\n return false;\n }\n\n // Files are no longer stored in grant files - they're tracked in the contract\n\n if (!obj.parameters || typeof obj.parameters !== \"object\") {\n return false;\n }\n\n // Validate optional expires field\n if (obj.expires !== undefined) {\n if (\n typeof obj.expires !== \"number\" ||\n obj.expires < 0 ||\n !Number.isInteger(obj.expires)\n ) {\n return false;\n }\n }\n\n return true;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/utils/grantFiles.ts"],"sourcesContent":["import { keccak256, toHex } from \"viem\";\nimport type { GrantFile, GrantPermissionParams } from \"../types/permissions\";\nimport { SerializationError, NetworkError } from \"../errors\";\n\ninterface GrantFileStorageResponse {\n success: boolean;\n error?: string;\n url?: string;\n}\n\n/**\n * Creates a grant file structure from permission parameters.\n *\n * @remarks\n * This function constructs the JSON structure that represents a permission grant\n * in the Vana protocol. The grant file contains all necessary information for\n * a grantee to perform operations on behalf of the grantor.\n *\n * @param params - The permission parameters to create the grant file from\n * @returns The constructed grant file object\n * @example\n * ```typescript\n * const grantFile = createGrantFile({\n * grantee: '0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36',\n * operation: 'llm_inference',\n * parameters: {\n * model: 'gpt-4',\n * maxTokens: 1000\n * },\n * expiresAt: Date.now() + 86400000 // 24 hours\n * });\n *\n * console.log(grantFile);\n * // {\n * // grantee: '0x742d...',\n * // operation: 'llm_inference',\n * // parameters: { model: 'gpt-4', maxTokens: 1000 },\n * // expires: 1234567890\n * // }\n * ```\n */\nexport function createGrantFile(params: GrantPermissionParams): GrantFile {\n const grantFile: GrantFile = {\n grantee: params.grantee,\n operation: params.operation,\n parameters: params.parameters,\n };\n\n // Add expiration if provided\n if (params.expiresAt) {\n grantFile.expires = params.expiresAt;\n }\n\n return grantFile;\n}\n\n/**\n * Stores a grant file in IPFS via the relayer service.\n *\n * @remarks\n * This function uploads the grant file to IPFS through the relayer's upload endpoint.\n * The returned URL can be stored on-chain as part of the permission grant, allowing\n * anyone to retrieve the detailed permission parameters later.\n *\n * @param grantFile - The grant file to store\n * @param relayerUrl - URL of the relayer service\n * @returns Promise resolving to the IPFS URL\n * @throws {NetworkError} When the upload fails or relayer is unavailable\n * @example\n * ```typescript\n * const grantFile = createGrantFile(params);\n *\n * try {\n * const ipfsUrl = await storeGrantFile(grantFile, 'https://relayer.vana.com');\n * console.log(`Grant file stored at: ${ipfsUrl}`);\n * // ipfsUrl: \"ipfs://QmHash123...\"\n * } catch (error) {\n * console.error('Failed to store grant file:', error);\n * }\n * ```\n */\nexport async function storeGrantFile(\n grantFile: GrantFile,\n relayerUrl: string,\n): Promise<string> {\n try {\n // Convert grant file to blob and use IPFS upload endpoint\n const grantFileBlob = new Blob([JSON.stringify(grantFile, null, 2)], {\n type: \"application/json\",\n });\n\n const formData = new FormData();\n formData.append(\"file\", grantFileBlob, \"grant-file.json\");\n\n const response = await fetch(`${relayerUrl}/api/ipfs/upload`, {\n method: \"POST\",\n body: formData,\n });\n\n if (!response.ok) {\n throw new NetworkError(\n `Failed to store grant file: ${response.statusText}`,\n new Error(`HTTP ${response.status}`),\n );\n }\n\n const responseData: unknown = await response.json();\n const data = responseData as GrantFileStorageResponse;\n\n if (!data.success) {\n throw new NetworkError(data.error ?? \"Failed to store grant file\");\n }\n\n if (!data.url) {\n throw new NetworkError(\"Upload succeeded but no URL was returned\");\n }\n return data.url; // The IPFS URL from the upload response\n } catch (error) {\n if (error instanceof NetworkError) {\n throw error;\n }\n throw new NetworkError(\n `Network error while storing grant file: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error as Error,\n );\n }\n}\n\n/**\n * Retrieves detailed grant file data from IPFS or HTTP storage.\n *\n * @remarks\n * **This is Step 2 of the performant two-step permission API.**\n *\n * Use this method to resolve detailed permission data (operation, parameters, etc.)\n * for specific grants after first getting the fast on-chain data using\n * `getUserPermissionGrantsOnChain()`. This design eliminates N+1 query problems\n * by allowing selective lazy-loading of expensive off-chain data.\n *\n * **Performance**: Single network request per grant file (typically 100-500ms).\n * **Reliability**: Tries multiple IPFS gateways as fallbacks if primary URL fails.\n *\n * @param grantUrl - The grant file URL from OnChainPermissionGrant.grantUrl\n * @param _relayerUrl - URL of the relayer service (optional, unused)\n * @param downloadRelayer - Optional download relayer for proxying CORS-restricted downloads\n * @param downloadRelayer.proxyDownload - Function to proxy download requests through application server\n * @returns Promise resolving to the complete grant file with operation details\n * @throws {NetworkError} When all retrieval attempts fail\n * @throws {SerializationError} When grant file format is invalid\n * @example\n * ```typescript\n * // Step 1: Fast on-chain data (no N+1 queries)\n * const grants = await vana.permissions.getUserPermissionGrantsOnChain();\n *\n * // Step 2: Lazy-load details for specific grant when needed\n * const grantFile = await retrieveGrantFile(grants[0].grantUrl);\n *\n * console.log(`Operation: ${grantFile.operation}`);\n * console.log(`Grantee: ${grantFile.grantee}`);\n * console.log(`Parameters:`, grantFile.parameters);\n *\n * // Only fetch details for grants user actually wants to see\n * for (const grant of selectedGrants) {\n * const details = await retrieveGrantFile(grant.grantUrl);\n * displayGrantDetails(details);\n * }\n * ```\n */\nexport async function retrieveGrantFile(\n grantUrl: string,\n _relayerUrl?: string,\n downloadRelayer?: { proxyDownload: (url: string) => Promise<Blob> },\n): Promise<GrantFile> {\n try {\n // Check if the URL is a gateway URL instead of ipfs:// protocol\n if (grantUrl.startsWith(\"http\") && grantUrl.includes(\"/ipfs/\")) {\n console.warn(\n `⚠️ Grant URL uses HTTP gateway format instead of ipfs:// protocol. ` +\n `Found: ${grantUrl}. ` +\n `Consider using ipfs:// format for better protocol-agnostic storage.`,\n );\n }\n\n // Use the unified download utility\n const { universalFetch } = await import(\"./download\");\n const response = await universalFetch(grantUrl, downloadRelayer);\n\n if (!response.ok) {\n throw new NetworkError(\n `Failed to retrieve grant file: HTTP ${response.status}`,\n );\n }\n\n const text = await response.text();\n const grantFile = JSON.parse(text);\n\n if (!validateGrantFile(grantFile)) {\n throw new NetworkError(`Invalid grant file format from ${grantUrl}`);\n }\n\n return grantFile;\n } catch (error) {\n if (error instanceof NetworkError) {\n throw error;\n }\n throw new NetworkError(\n `Error retrieving grant file: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error as Error,\n );\n }\n}\n\n/**\n * Generates a content hash for a grant file.\n * This can be used for integrity verification.\n *\n * @remarks\n * Creates a deterministic keccak256 hash of the grant file by first sorting\n * all object keys recursively to ensure consistent hashing regardless of\n * property order. This hash can be used to verify grant file integrity\n * or as a unique identifier.\n *\n * @param grantFile - The grant file to generate a hash for\n * @returns The keccak256 hash of the grant file as a hex string\n * @throws {SerializationError} When the grant file cannot be serialized\n * @example\n * ```typescript\n * const grantFile = {\n * grantee: '0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36',\n * operation: 'read',\n * parameters: { version: '1.0', mode: 'full' }\n * };\n *\n * const hash = getGrantFileHash(grantFile);\n * console.log(`Grant file hash: ${hash}`);\n * // \"0x1234567890abcdef...\"\n *\n * // Same grant file with different property order produces same hash\n * const grantFile2 = {\n * operation: 'read',\n * parameters: { mode: 'full', version: '1.0' },\n * grantee: '0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36'\n * };\n *\n * const hash2 = getGrantFileHash(grantFile2);\n * console.log(hash === hash2); // true\n * ```\n */\nexport function getGrantFileHash(grantFile: GrantFile): string {\n try {\n // Create a stable JSON representation\n const sortedFile: GrantFile = {\n grantee: grantFile.grantee,\n operation: grantFile.operation,\n parameters: sortObjectKeys(grantFile.parameters) as Record<\n string,\n unknown\n >,\n };\n\n // Add expires if present\n if (grantFile.expires !== undefined) {\n sortedFile.expires = grantFile.expires;\n }\n\n const jsonString = JSON.stringify(sortedFile);\n console.info(`Hash: ${keccak256(toHex(jsonString))}`);\n return keccak256(toHex(jsonString));\n } catch (error) {\n throw new SerializationError(\n `Failed to generate grant file hash: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n}\n\n/**\n * Recursively sorts object keys for stable serialization.\n *\n * @param obj - The object to sort keys recursively\n * @returns The object with all keys sorted recursively\n */\nfunction sortObjectKeys(obj: unknown): unknown {\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => sortObjectKeys(item));\n }\n\n const sortedObj: Record<string, unknown> = {};\n Object.keys(obj as Record<string, unknown>)\n .sort()\n .forEach((key) => {\n sortedObj[key] = sortObjectKeys((obj as Record<string, unknown>)[key]);\n });\n\n return sortedObj;\n}\n\n/**\n * Validates that a grant file has the required structure.\n *\n * @remarks\n * Performs runtime validation to ensure data conforms to the GrantFile interface.\n * Checks for required fields (grantee, operation, parameters) and validates their\n * types and formats. This is a type guard function that enables TypeScript to\n * narrow the type when it returns true.\n *\n * @param data - The data to validate as a grant file\n * @returns True if the data is a valid grant file, false otherwise\n * @example\n * ```typescript\n * const unknownData = await fetch(url).then(r => r.json());\n *\n * if (validateGrantFile(unknownData)) {\n * // TypeScript now knows unknownData is a GrantFile\n * console.log(`Grant for operation: ${unknownData.operation}`);\n * console.log(`Grantee: ${unknownData.grantee}`);\n * } else {\n * throw new Error('Invalid grant file format');\n * }\n *\n * // Validation examples:\n * validateGrantFile({\n * grantee: '0x742d35Cc6558Fd4D9e9E0E888F0462ef6919Bd36',\n * operation: 'read',\n * parameters: {}\n * }); // true\n *\n * validateGrantFile({\n * grantee: 'invalid-address',\n * operation: 'read',\n * parameters: {}\n * }); // false (invalid address format)\n *\n * validateGrantFile({\n * operation: 'read',\n * parameters: {}\n * }); // false (missing grantee)\n * ```\n */\nexport function validateGrantFile(data: unknown): data is GrantFile {\n if (!data || typeof data !== \"object\") {\n return false;\n }\n\n const obj = data as Record<string, unknown>;\n\n // Validate required fields\n // Validate grantee address\n if (\n typeof obj.grantee !== \"string\" ||\n !obj.grantee.match(/^0x[a-fA-F0-9]{40}$/)\n ) {\n return false;\n }\n\n if (typeof obj.operation !== \"string\" || obj.operation.length === 0) {\n return false;\n }\n\n // Files are no longer stored in grant files - they're tracked in the contract\n\n if (!obj.parameters || typeof obj.parameters !== \"object\") {\n return false;\n }\n\n // Validate optional expires field\n if (obj.expires !== undefined) {\n if (\n typeof obj.expires !== \"number\" ||\n obj.expires < 0 ||\n !Number.isInteger(obj.expires)\n ) {\n return false;\n }\n }\n\n return true;\n}\n"],"mappings":"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","names":[]}
@@ -209,7 +209,7 @@ function validateGranteeAccess(grantFile, requestingAddress) {
209
209
  }
210
210
  function validateGrantExpiry(grantFile, currentTime) {
211
211
  if (grantFile.expires) {
212
- const now = currentTime || Math.floor(Date.now() / 1e3);
212
+ const now = currentTime !== void 0 ? currentTime : Math.floor(Date.now() / 1e3);
213
213
  if (now > grantFile.expires) {
214
214
  throw new GrantExpiredError(
215
215
  "Permission denied: grant has expired",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/grantValidation.ts"],"sourcesContent":["import { Address, getAddress } from \"viem\";\nimport Ajv, { type ValidateFunction } from \"ajv\";\nimport addFormats from \"ajv-formats\";\nimport type { GrantFile } from \"../types/permissions\";\nimport grantFileSchema from \"../schemas/grantFile.schema.json\";\n\n/**\n * Base error class for grant validation failures\n *\n * @category Permissions\n */\nexport class GrantValidationError extends Error {\n constructor(\n message: string,\n public details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = \"GrantValidationError\";\n }\n}\n\n/**\n * Error thrown when a grant has expired\n *\n * @category Permissions\n */\nexport class GrantExpiredError extends GrantValidationError {\n constructor(\n message: string,\n public expires: number,\n public currentTime: number,\n ) {\n super(message, { expires, currentTime });\n this.name = \"GrantExpiredError\";\n }\n}\n\n/**\n * Error thrown when grantee doesn't match requesting address\n *\n * @category Permissions\n */\nexport class GranteeMismatchError extends GrantValidationError {\n constructor(\n message: string,\n public grantee: Address,\n public requestingAddress: Address,\n ) {\n super(message, { grantee, requestingAddress });\n this.name = \"GranteeMismatchError\";\n }\n}\n\n/**\n * Error thrown when operation is not allowed by grant\n *\n * @category Permissions\n */\nexport class OperationNotAllowedError extends GrantValidationError {\n constructor(\n message: string,\n public grantedOperation: string,\n public requestedOperation: string,\n ) {\n super(message, { grantedOperation, requestedOperation });\n this.name = \"OperationNotAllowedError\";\n }\n}\n\n/**\n * Error thrown when grant file structure is invalid\n *\n * @category Permissions\n */\nexport class GrantSchemaError extends GrantValidationError {\n constructor(\n message: string,\n public schemaErrors: unknown[],\n public invalidData: unknown,\n ) {\n super(message, { errors: schemaErrors, data: invalidData });\n this.name = \"GrantSchemaError\";\n }\n}\n\n/**\n * Ajv instance for grant file validation with draft 2020-12 support\n */\nconst ajv = new Ajv({\n strict: true,\n removeAdditional: false,\n useDefaults: false,\n coerceTypes: false,\n});\n\n// Add format validators (email, date, etc.)\naddFormats(ajv);\n\n/**\n * Compiled grant file schema validator\n */\nconst validateGrantFileSchema: ValidateFunction = ajv.compile(grantFileSchema);\n\n/**\n * Options for grant validation\n *\n * @category Permissions\n */\nexport interface GrantValidationOptions {\n /** Enable JSON schema validation (default: true) */\n schema?: boolean;\n /** Grantee address to validate access for */\n grantee?: Address;\n /** Operation to validate permission for */\n operation?: string;\n /** Override current time for expiry checking (Unix timestamp) */\n currentTime?: number;\n /** Return detailed results instead of throwing (default: false) */\n throwOnError?: boolean;\n}\n\n/**\n * Detailed validation result\n *\n * @category Permissions\n */\nexport interface GrantValidationResult {\n /** Whether validation passed */\n valid: boolean;\n /** Validation errors encountered */\n errors: Array<{\n type: \"schema\" | \"business\";\n field?: string;\n message: string;\n error?: Error;\n }>;\n /** The validated grant file (if validation passed) */\n grant?: GrantFile;\n}\n\n/**\n * Validates a grant file with comprehensive schema and business rule checking.\n *\n * This function provides flexible validation with TypeScript overloads:\n * - When `throwOnError` is false (or `{ throwOnError: false }`), returns a detailed validation result\n * - When `throwOnError` is true (default), throws specific errors or returns the validated grant\n *\n * @param data - The grant file data to validate (unknown type for safety)\n * @param options - Validation options including grantee, operation, files, etc.\n * @returns Either a GrantFile (when throwing) or GrantValidationResult (when not throwing)\n * @throws {GrantSchemaError} When the grant file structure is invalid\n * @throws {GrantExpiredError} When the grant has expired\n * @throws {GranteeMismatchError} When the grantee doesn't match the requesting address\n * @throws {OperationNotAllowedError} When the requested operation is not allowed\n * @example\n * ```typescript\n * // Throwing mode (default) - returns GrantFile or throws\n * const grant = validateGrant(data, {\n * grantee: '0x123...',\n * operation: 'llm_inference',\n * });\n *\n * // Non-throwing mode - returns validation result\n * const result = validateGrant(data, {\n * grantee: '0x123...',\n * throwOnError: false\n * });\n * if (result.valid) {\n * console.log('Grant is valid:', result.grant);\n * } else {\n * console.log('Validation errors:', result.errors);\n * }\n * ```\n */\n\nexport function validateGrant(\n data: unknown,\n options: GrantValidationOptions & { throwOnError: false },\n): GrantValidationResult;\n\nexport function validateGrant(\n data: unknown,\n options?:\n | Omit<GrantValidationOptions, \"throwOnError\">\n | (GrantValidationOptions & { throwOnError?: true }),\n): GrantFile;\n\n/**\n * Implementation function for grant validation with flexible return types\n *\n * @param data - The grant file data to validate\n * @param options - Validation configuration options\n * @returns Either a GrantFile or GrantValidationResult depending on throwOnError setting\n */\nexport function validateGrant(\n data: unknown,\n options: GrantValidationOptions = {},\n): GrantFile | GrantValidationResult {\n const {\n schema = true,\n grantee,\n operation,\n currentTime,\n throwOnError = true,\n } = options;\n\n const errors: GrantValidationResult[\"errors\"] = [];\n let grant: GrantFile | undefined;\n\n // 1. Schema Validation\n if (schema) {\n try {\n if (validateGrantFileSchema(data)) {\n grant = data as GrantFile;\n } else {\n throw new GrantValidationError(\"Invalid grant file schema\");\n }\n } catch (error) {\n if (error instanceof GrantValidationError) {\n const schemaError = new GrantSchemaError(\n error.message,\n Array.isArray(error.details?.errors) ? error.details.errors : [],\n data,\n );\n errors.push({\n type: \"schema\",\n message: error.message,\n error: schemaError,\n });\n } else {\n errors.push({\n type: \"schema\",\n message: `Schema validation failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error: error instanceof Error ? error : new Error(\"Unknown error\"),\n });\n }\n }\n } else {\n // Minimal type assertion if schema validation is skipped\n grant = data as GrantFile;\n }\n\n // 2. Business Logic Validation (only if we have a valid grant)\n if (grant) {\n // Check grantee access\n if (grantee) {\n try {\n validateGranteeAccess(grant, grantee);\n } catch (error) {\n const field = extractFieldFromBusinessError(error);\n errors.push({\n type: \"business\",\n field,\n message:\n error instanceof Error\n ? error.message\n : \"Unknown business rule error\",\n error: error instanceof Error ? error : new Error(\"Unknown error\"),\n });\n }\n }\n\n // Check expiration\n try {\n validateGrantExpiry(grant, currentTime);\n } catch (error) {\n const field = extractFieldFromBusinessError(error);\n errors.push({\n type: \"business\",\n field,\n message:\n error instanceof Error\n ? error.message\n : \"Unknown business rule error\",\n error: error instanceof Error ? error : new Error(\"Unknown error\"),\n });\n }\n\n // Check operation access\n if (operation) {\n try {\n validateOperationAccess(grant, operation);\n } catch (error) {\n const field = extractFieldFromBusinessError(error);\n errors.push({\n type: \"business\",\n field,\n message:\n error instanceof Error\n ? error.message\n : \"Unknown business rule error\",\n error: error instanceof Error ? error : new Error(\"Unknown error\"),\n });\n }\n }\n }\n\n // 3. Return Results\n if (errors.length > 0) {\n if (throwOnError) {\n // Throw the most specific error we have\n const firstError = errors[0];\n if (firstError.error) {\n throw firstError.error;\n } else {\n const combinedMessage = errors.map((e) => e.message).join(\"; \");\n throw new GrantValidationError(\n `Grant validation failed: ${combinedMessage}`,\n { errors, data },\n );\n }\n }\n\n return { valid: false, errors, grant };\n }\n\n if (throwOnError) {\n return grant as GrantFile;\n } else {\n return { valid: true, errors: [], grant: grant as GrantFile };\n }\n}\n\n/**\n * Helper function to extract field name from business validation errors\n *\n * @param error - The validation error to extract field information from\n * @returns The field name associated with the error, or undefined if not applicable\n */\nfunction extractFieldFromBusinessError(error: unknown): string | undefined {\n if (error instanceof GrantExpiredError) return \"expires\";\n if (error instanceof GranteeMismatchError) return \"grantee\";\n if (error instanceof OperationNotAllowedError) return \"operation\";\n return undefined;\n}\n\n/**\n * Validates that a grant file allows access for a specific grantee\n *\n * @param grantFile - The grant file to validate access for\n * @param requestingAddress - The address requesting access to check against the grantee\n */\nexport function validateGranteeAccess(\n grantFile: GrantFile,\n requestingAddress: Address,\n): void {\n const normalizedGrantee = getAddress(grantFile.grantee);\n const normalizedRequesting = getAddress(requestingAddress);\n\n if (normalizedGrantee !== normalizedRequesting) {\n throw new GranteeMismatchError(\n \"Permission denied: requesting address does not match grantee\",\n grantFile.grantee,\n requestingAddress,\n );\n }\n}\n\n/**\n * Validates that a grant has not expired (if expiry is set)\n *\n * @param grantFile - The grant file to check expiration for\n * @param currentTime - Optional override for current time (Unix timestamp)\n */\nexport function validateGrantExpiry(\n grantFile: GrantFile,\n currentTime?: number,\n): void {\n if (grantFile.expires) {\n const now = currentTime || Math.floor(Date.now() / 1000); // Current Unix timestamp\n\n if (now > grantFile.expires) {\n throw new GrantExpiredError(\n \"Permission denied: grant has expired\",\n grantFile.expires,\n now,\n );\n }\n }\n}\n\n/**\n * Validates that a grant allows a specific operation\n *\n * @param grantFile - The grant file to validate operation access for\n * @param requestedOperation - The operation being requested to validate against the grant\n */\nexport function validateOperationAccess(\n grantFile: GrantFile,\n requestedOperation: string,\n): void {\n if (grantFile.operation !== requestedOperation) {\n throw new OperationNotAllowedError(\n \"Permission denied: operation not allowed by grant\",\n grantFile.operation,\n requestedOperation,\n );\n }\n}\n"],"mappings":"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","names":["Ajv","addFormats","grantFileSchema"]}
1
+ {"version":3,"sources":["../../src/utils/grantValidation.ts"],"sourcesContent":["import type { Address } from \"viem\";\nimport { getAddress } from \"viem\";\nimport Ajv, { type ValidateFunction } from \"ajv\";\nimport addFormats from \"ajv-formats\";\nimport type { GrantFile } from \"../types/permissions\";\nimport grantFileSchema from \"../schemas/grantFile.schema.json\";\n\n/**\n * Base error class for grant validation failures\n *\n * @category Permissions\n */\nexport class GrantValidationError extends Error {\n constructor(\n message: string,\n public details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = \"GrantValidationError\";\n }\n}\n\n/**\n * Error thrown when a grant has expired\n *\n * @category Permissions\n */\nexport class GrantExpiredError extends GrantValidationError {\n constructor(\n message: string,\n public expires: number,\n public currentTime: number,\n ) {\n super(message, { expires, currentTime });\n this.name = \"GrantExpiredError\";\n }\n}\n\n/**\n * Error thrown when grantee doesn't match requesting address\n *\n * @category Permissions\n */\nexport class GranteeMismatchError extends GrantValidationError {\n constructor(\n message: string,\n public grantee: Address,\n public requestingAddress: Address,\n ) {\n super(message, { grantee, requestingAddress });\n this.name = \"GranteeMismatchError\";\n }\n}\n\n/**\n * Error thrown when operation is not allowed by grant\n *\n * @category Permissions\n */\nexport class OperationNotAllowedError extends GrantValidationError {\n constructor(\n message: string,\n public grantedOperation: string,\n public requestedOperation: string,\n ) {\n super(message, { grantedOperation, requestedOperation });\n this.name = \"OperationNotAllowedError\";\n }\n}\n\n/**\n * Error thrown when grant file structure is invalid\n *\n * @category Permissions\n */\nexport class GrantSchemaError extends GrantValidationError {\n constructor(\n message: string,\n public schemaErrors: unknown[],\n public invalidData: unknown,\n ) {\n super(message, { errors: schemaErrors, data: invalidData });\n this.name = \"GrantSchemaError\";\n }\n}\n\n/**\n * Ajv instance for grant file validation with draft 2020-12 support\n */\nconst ajv = new Ajv({\n strict: true,\n removeAdditional: false,\n useDefaults: false,\n coerceTypes: false,\n});\n\n// Add format validators (email, date, etc.)\naddFormats(ajv);\n\n/**\n * Compiled grant file schema validator\n */\nconst validateGrantFileSchema: ValidateFunction = ajv.compile(grantFileSchema);\n\n/**\n * Options for grant validation\n *\n * @category Permissions\n */\nexport interface GrantValidationOptions {\n /** Enable JSON schema validation (default: true) */\n schema?: boolean;\n /** Grantee address to validate access for */\n grantee?: Address;\n /** Operation to validate permission for */\n operation?: string;\n /** Override current time for expiry checking (Unix timestamp) */\n currentTime?: number;\n /** Return detailed results instead of throwing (default: false) */\n throwOnError?: boolean;\n}\n\n/**\n * Detailed validation result\n *\n * @category Permissions\n */\nexport interface GrantValidationResult {\n /** Whether validation passed */\n valid: boolean;\n /** Validation errors encountered */\n errors: Array<{\n type: \"schema\" | \"business\";\n field?: string;\n message: string;\n error?: Error;\n }>;\n /** The validated grant file (if validation passed) */\n grant?: GrantFile;\n}\n\n/**\n * Validates a grant file with comprehensive schema and business rule checking.\n *\n * This function provides flexible validation with TypeScript overloads:\n * - When `throwOnError` is false (or `{ throwOnError: false }`), returns a detailed validation result\n * - When `throwOnError` is true (default), throws specific errors or returns the validated grant\n *\n * @param data - The grant file data to validate (unknown type for safety)\n * @param options - Validation options including grantee, operation, files, etc.\n * @returns Either a GrantFile (when throwing) or GrantValidationResult (when not throwing)\n * @throws {GrantSchemaError} When the grant file structure is invalid\n * @throws {GrantExpiredError} When the grant has expired\n * @throws {GranteeMismatchError} When the grantee doesn't match the requesting address\n * @throws {OperationNotAllowedError} When the requested operation is not allowed\n * @example\n * ```typescript\n * // Throwing mode (default) - returns GrantFile or throws\n * const grant = validateGrant(data, {\n * grantee: '0x123...',\n * operation: 'llm_inference',\n * });\n *\n * // Non-throwing mode - returns validation result\n * const result = validateGrant(data, {\n * grantee: '0x123...',\n * throwOnError: false\n * });\n * if (result.valid) {\n * console.log('Grant is valid:', result.grant);\n * } else {\n * console.log('Validation errors:', result.errors);\n * }\n * ```\n */\n\nexport function validateGrant(\n data: unknown,\n options: GrantValidationOptions & { throwOnError: false },\n): GrantValidationResult;\n\nexport function validateGrant(\n data: unknown,\n options?:\n | Omit<GrantValidationOptions, \"throwOnError\">\n | (GrantValidationOptions & { throwOnError?: true }),\n): GrantFile;\n\n/**\n * Implementation function for grant validation with flexible return types\n *\n * @param data - The grant file data to validate\n * @param options - Validation configuration options\n * @returns Either a GrantFile or GrantValidationResult depending on throwOnError setting\n */\nexport function validateGrant(\n data: unknown,\n options: GrantValidationOptions = {},\n): GrantFile | GrantValidationResult {\n const {\n schema = true,\n grantee,\n operation,\n currentTime,\n throwOnError = true,\n } = options;\n\n const errors: GrantValidationResult[\"errors\"] = [];\n let grant: GrantFile | undefined;\n\n // 1. Schema Validation\n if (schema) {\n try {\n if (validateGrantFileSchema(data)) {\n grant = data as GrantFile;\n } else {\n throw new GrantValidationError(\"Invalid grant file schema\");\n }\n } catch (error) {\n if (error instanceof GrantValidationError) {\n const schemaError = new GrantSchemaError(\n error.message,\n Array.isArray(error.details?.errors) ? error.details.errors : [],\n data,\n );\n errors.push({\n type: \"schema\",\n message: error.message,\n error: schemaError,\n });\n } else {\n errors.push({\n type: \"schema\",\n message: `Schema validation failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error: error instanceof Error ? error : new Error(\"Unknown error\"),\n });\n }\n }\n } else {\n // Minimal type assertion if schema validation is skipped\n grant = data as GrantFile;\n }\n\n // 2. Business Logic Validation (only if we have a valid grant)\n if (grant) {\n // Check grantee access\n if (grantee) {\n try {\n validateGranteeAccess(grant, grantee);\n } catch (error) {\n const field = extractFieldFromBusinessError(error);\n errors.push({\n type: \"business\",\n field,\n message:\n error instanceof Error\n ? error.message\n : \"Unknown business rule error\",\n error: error instanceof Error ? error : new Error(\"Unknown error\"),\n });\n }\n }\n\n // Check expiration\n try {\n validateGrantExpiry(grant, currentTime);\n } catch (error) {\n const field = extractFieldFromBusinessError(error);\n errors.push({\n type: \"business\",\n field,\n message:\n error instanceof Error\n ? error.message\n : \"Unknown business rule error\",\n error: error instanceof Error ? error : new Error(\"Unknown error\"),\n });\n }\n\n // Check operation access\n if (operation) {\n try {\n validateOperationAccess(grant, operation);\n } catch (error) {\n const field = extractFieldFromBusinessError(error);\n errors.push({\n type: \"business\",\n field,\n message:\n error instanceof Error\n ? error.message\n : \"Unknown business rule error\",\n error: error instanceof Error ? error : new Error(\"Unknown error\"),\n });\n }\n }\n }\n\n // 3. Return Results\n if (errors.length > 0) {\n if (throwOnError) {\n // Throw the most specific error we have\n const firstError = errors[0];\n if (firstError.error) {\n throw firstError.error;\n } else {\n const combinedMessage = errors.map((e) => e.message).join(\"; \");\n throw new GrantValidationError(\n `Grant validation failed: ${combinedMessage}`,\n { errors, data },\n );\n }\n }\n\n return { valid: false, errors, grant };\n }\n\n if (throwOnError) {\n return grant as GrantFile;\n } else {\n return { valid: true, errors: [], grant: grant as GrantFile };\n }\n}\n\n/**\n * Helper function to extract field name from business validation errors\n *\n * @param error - The validation error to extract field information from\n * @returns The field name associated with the error, or undefined if not applicable\n */\nfunction extractFieldFromBusinessError(error: unknown): string | undefined {\n if (error instanceof GrantExpiredError) return \"expires\";\n if (error instanceof GranteeMismatchError) return \"grantee\";\n if (error instanceof OperationNotAllowedError) return \"operation\";\n return undefined;\n}\n\n/**\n * Validates that a grant file allows access for a specific grantee\n *\n * @param grantFile - The grant file to validate access for\n * @param requestingAddress - The address requesting access to check against the grantee\n */\nexport function validateGranteeAccess(\n grantFile: GrantFile,\n requestingAddress: Address,\n): void {\n const normalizedGrantee = getAddress(grantFile.grantee);\n const normalizedRequesting = getAddress(requestingAddress);\n\n if (normalizedGrantee !== normalizedRequesting) {\n throw new GranteeMismatchError(\n \"Permission denied: requesting address does not match grantee\",\n grantFile.grantee,\n requestingAddress,\n );\n }\n}\n\n/**\n * Validates that a grant has not expired (if expiry is set)\n *\n * @param grantFile - The grant file to check expiration for\n * @param currentTime - Optional override for current time (Unix timestamp)\n */\nexport function validateGrantExpiry(\n grantFile: GrantFile,\n currentTime?: number,\n): void {\n if (grantFile.expires) {\n const now =\n currentTime !== undefined ? currentTime : Math.floor(Date.now() / 1000); // Current Unix timestamp\n\n if (now > grantFile.expires) {\n throw new GrantExpiredError(\n \"Permission denied: grant has expired\",\n grantFile.expires,\n now,\n );\n }\n }\n}\n\n/**\n * Validates that a grant allows a specific operation\n *\n * @param grantFile - The grant file to validate operation access for\n * @param requestedOperation - The operation being requested to validate against the grant\n */\nexport function validateOperationAccess(\n grantFile: GrantFile,\n requestedOperation: string,\n): void {\n if (grantFile.operation !== requestedOperation) {\n throw new OperationNotAllowedError(\n \"Permission denied: operation not allowed by grant\",\n grantFile.operation,\n requestedOperation,\n );\n }\n}\n"],"mappings":"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","names":["Ajv","addFormats","grantFileSchema"]}
@@ -1,12 +1,11 @@
1
- import { Address } from 'viem';
2
- import { GrantFile } from '../types/permissions.js';
3
-
1
+ import type { Address } from "viem";
2
+ import type { GrantFile } from "../types/permissions";
4
3
  /**
5
4
  * Base error class for grant validation failures
6
5
  *
7
6
  * @category Permissions
8
7
  */
9
- declare class GrantValidationError extends Error {
8
+ export declare class GrantValidationError extends Error {
10
9
  details?: Record<string, unknown> | undefined;
11
10
  constructor(message: string, details?: Record<string, unknown> | undefined);
12
11
  }
@@ -15,7 +14,7 @@ declare class GrantValidationError extends Error {
15
14
  *
16
15
  * @category Permissions
17
16
  */
18
- declare class GrantExpiredError extends GrantValidationError {
17
+ export declare class GrantExpiredError extends GrantValidationError {
19
18
  expires: number;
20
19
  currentTime: number;
21
20
  constructor(message: string, expires: number, currentTime: number);
@@ -25,7 +24,7 @@ declare class GrantExpiredError extends GrantValidationError {
25
24
  *
26
25
  * @category Permissions
27
26
  */
28
- declare class GranteeMismatchError extends GrantValidationError {
27
+ export declare class GranteeMismatchError extends GrantValidationError {
29
28
  grantee: Address;
30
29
  requestingAddress: Address;
31
30
  constructor(message: string, grantee: Address, requestingAddress: Address);
@@ -35,7 +34,7 @@ declare class GranteeMismatchError extends GrantValidationError {
35
34
  *
36
35
  * @category Permissions
37
36
  */
38
- declare class OperationNotAllowedError extends GrantValidationError {
37
+ export declare class OperationNotAllowedError extends GrantValidationError {
39
38
  grantedOperation: string;
40
39
  requestedOperation: string;
41
40
  constructor(message: string, grantedOperation: string, requestedOperation: string);
@@ -45,7 +44,7 @@ declare class OperationNotAllowedError extends GrantValidationError {
45
44
  *
46
45
  * @category Permissions
47
46
  */
48
- declare class GrantSchemaError extends GrantValidationError {
47
+ export declare class GrantSchemaError extends GrantValidationError {
49
48
  schemaErrors: unknown[];
50
49
  invalidData: unknown;
51
50
  constructor(message: string, schemaErrors: unknown[], invalidData: unknown);
@@ -55,7 +54,7 @@ declare class GrantSchemaError extends GrantValidationError {
55
54
  *
56
55
  * @category Permissions
57
56
  */
58
- interface GrantValidationOptions {
57
+ export interface GrantValidationOptions {
59
58
  /** Enable JSON schema validation (default: true) */
60
59
  schema?: boolean;
61
60
  /** Grantee address to validate access for */
@@ -72,7 +71,7 @@ interface GrantValidationOptions {
72
71
  *
73
72
  * @category Permissions
74
73
  */
75
- interface GrantValidationResult {
74
+ export interface GrantValidationResult {
76
75
  /** Whether validation passed */
77
76
  valid: boolean;
78
77
  /** Validation errors encountered */
@@ -119,10 +118,10 @@ interface GrantValidationResult {
119
118
  * }
120
119
  * ```
121
120
  */
122
- declare function validateGrant(data: unknown, options: GrantValidationOptions & {
121
+ export declare function validateGrant(data: unknown, options: GrantValidationOptions & {
123
122
  throwOnError: false;
124
123
  }): GrantValidationResult;
125
- declare function validateGrant(data: unknown, options?: Omit<GrantValidationOptions, "throwOnError"> | (GrantValidationOptions & {
124
+ export declare function validateGrant(data: unknown, options?: Omit<GrantValidationOptions, "throwOnError"> | (GrantValidationOptions & {
126
125
  throwOnError?: true;
127
126
  })): GrantFile;
128
127
  /**
@@ -131,20 +130,18 @@ declare function validateGrant(data: unknown, options?: Omit<GrantValidationOpti
131
130
  * @param grantFile - The grant file to validate access for
132
131
  * @param requestingAddress - The address requesting access to check against the grantee
133
132
  */
134
- declare function validateGranteeAccess(grantFile: GrantFile, requestingAddress: Address): void;
133
+ export declare function validateGranteeAccess(grantFile: GrantFile, requestingAddress: Address): void;
135
134
  /**
136
135
  * Validates that a grant has not expired (if expiry is set)
137
136
  *
138
137
  * @param grantFile - The grant file to check expiration for
139
138
  * @param currentTime - Optional override for current time (Unix timestamp)
140
139
  */
141
- declare function validateGrantExpiry(grantFile: GrantFile, currentTime?: number): void;
140
+ export declare function validateGrantExpiry(grantFile: GrantFile, currentTime?: number): void;
142
141
  /**
143
142
  * Validates that a grant allows a specific operation
144
143
  *
145
144
  * @param grantFile - The grant file to validate operation access for
146
145
  * @param requestedOperation - The operation being requested to validate against the grant
147
146
  */
148
- declare function validateOperationAccess(grantFile: GrantFile, requestedOperation: string): void;
149
-
150
- export { GrantExpiredError, GrantSchemaError, GrantValidationError, type GrantValidationOptions, type GrantValidationResult, GranteeMismatchError, OperationNotAllowedError, validateGrant, validateGrantExpiry, validateGranteeAccess, validateOperationAccess };
147
+ export declare function validateOperationAccess(grantFile: GrantFile, requestedOperation: string): void;
@@ -168,7 +168,7 @@ function validateGranteeAccess(grantFile, requestingAddress) {
168
168
  }
169
169
  function validateGrantExpiry(grantFile, currentTime) {
170
170
  if (grantFile.expires) {
171
- const now = currentTime || Math.floor(Date.now() / 1e3);
171
+ const now = currentTime !== void 0 ? currentTime : Math.floor(Date.now() / 1e3);
172
172
  if (now > grantFile.expires) {
173
173
  throw new GrantExpiredError(
174
174
  "Permission denied: grant has expired",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/grantValidation.ts"],"sourcesContent":["import { Address, getAddress } from \"viem\";\nimport Ajv, { type ValidateFunction } from \"ajv\";\nimport addFormats from \"ajv-formats\";\nimport type { GrantFile } from \"../types/permissions\";\nimport grantFileSchema from \"../schemas/grantFile.schema.json\";\n\n/**\n * Base error class for grant validation failures\n *\n * @category Permissions\n */\nexport class GrantValidationError extends Error {\n constructor(\n message: string,\n public details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = \"GrantValidationError\";\n }\n}\n\n/**\n * Error thrown when a grant has expired\n *\n * @category Permissions\n */\nexport class GrantExpiredError extends GrantValidationError {\n constructor(\n message: string,\n public expires: number,\n public currentTime: number,\n ) {\n super(message, { expires, currentTime });\n this.name = \"GrantExpiredError\";\n }\n}\n\n/**\n * Error thrown when grantee doesn't match requesting address\n *\n * @category Permissions\n */\nexport class GranteeMismatchError extends GrantValidationError {\n constructor(\n message: string,\n public grantee: Address,\n public requestingAddress: Address,\n ) {\n super(message, { grantee, requestingAddress });\n this.name = \"GranteeMismatchError\";\n }\n}\n\n/**\n * Error thrown when operation is not allowed by grant\n *\n * @category Permissions\n */\nexport class OperationNotAllowedError extends GrantValidationError {\n constructor(\n message: string,\n public grantedOperation: string,\n public requestedOperation: string,\n ) {\n super(message, { grantedOperation, requestedOperation });\n this.name = \"OperationNotAllowedError\";\n }\n}\n\n/**\n * Error thrown when grant file structure is invalid\n *\n * @category Permissions\n */\nexport class GrantSchemaError extends GrantValidationError {\n constructor(\n message: string,\n public schemaErrors: unknown[],\n public invalidData: unknown,\n ) {\n super(message, { errors: schemaErrors, data: invalidData });\n this.name = \"GrantSchemaError\";\n }\n}\n\n/**\n * Ajv instance for grant file validation with draft 2020-12 support\n */\nconst ajv = new Ajv({\n strict: true,\n removeAdditional: false,\n useDefaults: false,\n coerceTypes: false,\n});\n\n// Add format validators (email, date, etc.)\naddFormats(ajv);\n\n/**\n * Compiled grant file schema validator\n */\nconst validateGrantFileSchema: ValidateFunction = ajv.compile(grantFileSchema);\n\n/**\n * Options for grant validation\n *\n * @category Permissions\n */\nexport interface GrantValidationOptions {\n /** Enable JSON schema validation (default: true) */\n schema?: boolean;\n /** Grantee address to validate access for */\n grantee?: Address;\n /** Operation to validate permission for */\n operation?: string;\n /** Override current time for expiry checking (Unix timestamp) */\n currentTime?: number;\n /** Return detailed results instead of throwing (default: false) */\n throwOnError?: boolean;\n}\n\n/**\n * Detailed validation result\n *\n * @category Permissions\n */\nexport interface GrantValidationResult {\n /** Whether validation passed */\n valid: boolean;\n /** Validation errors encountered */\n errors: Array<{\n type: \"schema\" | \"business\";\n field?: string;\n message: string;\n error?: Error;\n }>;\n /** The validated grant file (if validation passed) */\n grant?: GrantFile;\n}\n\n/**\n * Validates a grant file with comprehensive schema and business rule checking.\n *\n * This function provides flexible validation with TypeScript overloads:\n * - When `throwOnError` is false (or `{ throwOnError: false }`), returns a detailed validation result\n * - When `throwOnError` is true (default), throws specific errors or returns the validated grant\n *\n * @param data - The grant file data to validate (unknown type for safety)\n * @param options - Validation options including grantee, operation, files, etc.\n * @returns Either a GrantFile (when throwing) or GrantValidationResult (when not throwing)\n * @throws {GrantSchemaError} When the grant file structure is invalid\n * @throws {GrantExpiredError} When the grant has expired\n * @throws {GranteeMismatchError} When the grantee doesn't match the requesting address\n * @throws {OperationNotAllowedError} When the requested operation is not allowed\n * @example\n * ```typescript\n * // Throwing mode (default) - returns GrantFile or throws\n * const grant = validateGrant(data, {\n * grantee: '0x123...',\n * operation: 'llm_inference',\n * });\n *\n * // Non-throwing mode - returns validation result\n * const result = validateGrant(data, {\n * grantee: '0x123...',\n * throwOnError: false\n * });\n * if (result.valid) {\n * console.log('Grant is valid:', result.grant);\n * } else {\n * console.log('Validation errors:', result.errors);\n * }\n * ```\n */\n\nexport function validateGrant(\n data: unknown,\n options: GrantValidationOptions & { throwOnError: false },\n): GrantValidationResult;\n\nexport function validateGrant(\n data: unknown,\n options?:\n | Omit<GrantValidationOptions, \"throwOnError\">\n | (GrantValidationOptions & { throwOnError?: true }),\n): GrantFile;\n\n/**\n * Implementation function for grant validation with flexible return types\n *\n * @param data - The grant file data to validate\n * @param options - Validation configuration options\n * @returns Either a GrantFile or GrantValidationResult depending on throwOnError setting\n */\nexport function validateGrant(\n data: unknown,\n options: GrantValidationOptions = {},\n): GrantFile | GrantValidationResult {\n const {\n schema = true,\n grantee,\n operation,\n currentTime,\n throwOnError = true,\n } = options;\n\n const errors: GrantValidationResult[\"errors\"] = [];\n let grant: GrantFile | undefined;\n\n // 1. Schema Validation\n if (schema) {\n try {\n if (validateGrantFileSchema(data)) {\n grant = data as GrantFile;\n } else {\n throw new GrantValidationError(\"Invalid grant file schema\");\n }\n } catch (error) {\n if (error instanceof GrantValidationError) {\n const schemaError = new GrantSchemaError(\n error.message,\n Array.isArray(error.details?.errors) ? error.details.errors : [],\n data,\n );\n errors.push({\n type: \"schema\",\n message: error.message,\n error: schemaError,\n });\n } else {\n errors.push({\n type: \"schema\",\n message: `Schema validation failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error: error instanceof Error ? error : new Error(\"Unknown error\"),\n });\n }\n }\n } else {\n // Minimal type assertion if schema validation is skipped\n grant = data as GrantFile;\n }\n\n // 2. Business Logic Validation (only if we have a valid grant)\n if (grant) {\n // Check grantee access\n if (grantee) {\n try {\n validateGranteeAccess(grant, grantee);\n } catch (error) {\n const field = extractFieldFromBusinessError(error);\n errors.push({\n type: \"business\",\n field,\n message:\n error instanceof Error\n ? error.message\n : \"Unknown business rule error\",\n error: error instanceof Error ? error : new Error(\"Unknown error\"),\n });\n }\n }\n\n // Check expiration\n try {\n validateGrantExpiry(grant, currentTime);\n } catch (error) {\n const field = extractFieldFromBusinessError(error);\n errors.push({\n type: \"business\",\n field,\n message:\n error instanceof Error\n ? error.message\n : \"Unknown business rule error\",\n error: error instanceof Error ? error : new Error(\"Unknown error\"),\n });\n }\n\n // Check operation access\n if (operation) {\n try {\n validateOperationAccess(grant, operation);\n } catch (error) {\n const field = extractFieldFromBusinessError(error);\n errors.push({\n type: \"business\",\n field,\n message:\n error instanceof Error\n ? error.message\n : \"Unknown business rule error\",\n error: error instanceof Error ? error : new Error(\"Unknown error\"),\n });\n }\n }\n }\n\n // 3. Return Results\n if (errors.length > 0) {\n if (throwOnError) {\n // Throw the most specific error we have\n const firstError = errors[0];\n if (firstError.error) {\n throw firstError.error;\n } else {\n const combinedMessage = errors.map((e) => e.message).join(\"; \");\n throw new GrantValidationError(\n `Grant validation failed: ${combinedMessage}`,\n { errors, data },\n );\n }\n }\n\n return { valid: false, errors, grant };\n }\n\n if (throwOnError) {\n return grant as GrantFile;\n } else {\n return { valid: true, errors: [], grant: grant as GrantFile };\n }\n}\n\n/**\n * Helper function to extract field name from business validation errors\n *\n * @param error - The validation error to extract field information from\n * @returns The field name associated with the error, or undefined if not applicable\n */\nfunction extractFieldFromBusinessError(error: unknown): string | undefined {\n if (error instanceof GrantExpiredError) return \"expires\";\n if (error instanceof GranteeMismatchError) return \"grantee\";\n if (error instanceof OperationNotAllowedError) return \"operation\";\n return undefined;\n}\n\n/**\n * Validates that a grant file allows access for a specific grantee\n *\n * @param grantFile - The grant file to validate access for\n * @param requestingAddress - The address requesting access to check against the grantee\n */\nexport function validateGranteeAccess(\n grantFile: GrantFile,\n requestingAddress: Address,\n): void {\n const normalizedGrantee = getAddress(grantFile.grantee);\n const normalizedRequesting = getAddress(requestingAddress);\n\n if (normalizedGrantee !== normalizedRequesting) {\n throw new GranteeMismatchError(\n \"Permission denied: requesting address does not match grantee\",\n grantFile.grantee,\n requestingAddress,\n );\n }\n}\n\n/**\n * Validates that a grant has not expired (if expiry is set)\n *\n * @param grantFile - The grant file to check expiration for\n * @param currentTime - Optional override for current time (Unix timestamp)\n */\nexport function validateGrantExpiry(\n grantFile: GrantFile,\n currentTime?: number,\n): void {\n if (grantFile.expires) {\n const now = currentTime || Math.floor(Date.now() / 1000); // Current Unix timestamp\n\n if (now > grantFile.expires) {\n throw new GrantExpiredError(\n \"Permission denied: grant has expired\",\n grantFile.expires,\n now,\n );\n }\n }\n}\n\n/**\n * Validates that a grant allows a specific operation\n *\n * @param grantFile - The grant file to validate operation access for\n * @param requestedOperation - The operation being requested to validate against the grant\n */\nexport function validateOperationAccess(\n grantFile: GrantFile,\n requestedOperation: string,\n): void {\n if (grantFile.operation !== requestedOperation) {\n throw new OperationNotAllowedError(\n \"Permission denied: operation not allowed by grant\",\n grantFile.operation,\n requestedOperation,\n );\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/utils/grantValidation.ts"],"sourcesContent":["import type { Address } from \"viem\";\nimport { getAddress } from \"viem\";\nimport Ajv, { type ValidateFunction } from \"ajv\";\nimport addFormats from \"ajv-formats\";\nimport type { GrantFile } from \"../types/permissions\";\nimport grantFileSchema from \"../schemas/grantFile.schema.json\";\n\n/**\n * Base error class for grant validation failures\n *\n * @category Permissions\n */\nexport class GrantValidationError extends Error {\n constructor(\n message: string,\n public details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = \"GrantValidationError\";\n }\n}\n\n/**\n * Error thrown when a grant has expired\n *\n * @category Permissions\n */\nexport class GrantExpiredError extends GrantValidationError {\n constructor(\n message: string,\n public expires: number,\n public currentTime: number,\n ) {\n super(message, { expires, currentTime });\n this.name = \"GrantExpiredError\";\n }\n}\n\n/**\n * Error thrown when grantee doesn't match requesting address\n *\n * @category Permissions\n */\nexport class GranteeMismatchError extends GrantValidationError {\n constructor(\n message: string,\n public grantee: Address,\n public requestingAddress: Address,\n ) {\n super(message, { grantee, requestingAddress });\n this.name = \"GranteeMismatchError\";\n }\n}\n\n/**\n * Error thrown when operation is not allowed by grant\n *\n * @category Permissions\n */\nexport class OperationNotAllowedError extends GrantValidationError {\n constructor(\n message: string,\n public grantedOperation: string,\n public requestedOperation: string,\n ) {\n super(message, { grantedOperation, requestedOperation });\n this.name = \"OperationNotAllowedError\";\n }\n}\n\n/**\n * Error thrown when grant file structure is invalid\n *\n * @category Permissions\n */\nexport class GrantSchemaError extends GrantValidationError {\n constructor(\n message: string,\n public schemaErrors: unknown[],\n public invalidData: unknown,\n ) {\n super(message, { errors: schemaErrors, data: invalidData });\n this.name = \"GrantSchemaError\";\n }\n}\n\n/**\n * Ajv instance for grant file validation with draft 2020-12 support\n */\nconst ajv = new Ajv({\n strict: true,\n removeAdditional: false,\n useDefaults: false,\n coerceTypes: false,\n});\n\n// Add format validators (email, date, etc.)\naddFormats(ajv);\n\n/**\n * Compiled grant file schema validator\n */\nconst validateGrantFileSchema: ValidateFunction = ajv.compile(grantFileSchema);\n\n/**\n * Options for grant validation\n *\n * @category Permissions\n */\nexport interface GrantValidationOptions {\n /** Enable JSON schema validation (default: true) */\n schema?: boolean;\n /** Grantee address to validate access for */\n grantee?: Address;\n /** Operation to validate permission for */\n operation?: string;\n /** Override current time for expiry checking (Unix timestamp) */\n currentTime?: number;\n /** Return detailed results instead of throwing (default: false) */\n throwOnError?: boolean;\n}\n\n/**\n * Detailed validation result\n *\n * @category Permissions\n */\nexport interface GrantValidationResult {\n /** Whether validation passed */\n valid: boolean;\n /** Validation errors encountered */\n errors: Array<{\n type: \"schema\" | \"business\";\n field?: string;\n message: string;\n error?: Error;\n }>;\n /** The validated grant file (if validation passed) */\n grant?: GrantFile;\n}\n\n/**\n * Validates a grant file with comprehensive schema and business rule checking.\n *\n * This function provides flexible validation with TypeScript overloads:\n * - When `throwOnError` is false (or `{ throwOnError: false }`), returns a detailed validation result\n * - When `throwOnError` is true (default), throws specific errors or returns the validated grant\n *\n * @param data - The grant file data to validate (unknown type for safety)\n * @param options - Validation options including grantee, operation, files, etc.\n * @returns Either a GrantFile (when throwing) or GrantValidationResult (when not throwing)\n * @throws {GrantSchemaError} When the grant file structure is invalid\n * @throws {GrantExpiredError} When the grant has expired\n * @throws {GranteeMismatchError} When the grantee doesn't match the requesting address\n * @throws {OperationNotAllowedError} When the requested operation is not allowed\n * @example\n * ```typescript\n * // Throwing mode (default) - returns GrantFile or throws\n * const grant = validateGrant(data, {\n * grantee: '0x123...',\n * operation: 'llm_inference',\n * });\n *\n * // Non-throwing mode - returns validation result\n * const result = validateGrant(data, {\n * grantee: '0x123...',\n * throwOnError: false\n * });\n * if (result.valid) {\n * console.log('Grant is valid:', result.grant);\n * } else {\n * console.log('Validation errors:', result.errors);\n * }\n * ```\n */\n\nexport function validateGrant(\n data: unknown,\n options: GrantValidationOptions & { throwOnError: false },\n): GrantValidationResult;\n\nexport function validateGrant(\n data: unknown,\n options?:\n | Omit<GrantValidationOptions, \"throwOnError\">\n | (GrantValidationOptions & { throwOnError?: true }),\n): GrantFile;\n\n/**\n * Implementation function for grant validation with flexible return types\n *\n * @param data - The grant file data to validate\n * @param options - Validation configuration options\n * @returns Either a GrantFile or GrantValidationResult depending on throwOnError setting\n */\nexport function validateGrant(\n data: unknown,\n options: GrantValidationOptions = {},\n): GrantFile | GrantValidationResult {\n const {\n schema = true,\n grantee,\n operation,\n currentTime,\n throwOnError = true,\n } = options;\n\n const errors: GrantValidationResult[\"errors\"] = [];\n let grant: GrantFile | undefined;\n\n // 1. Schema Validation\n if (schema) {\n try {\n if (validateGrantFileSchema(data)) {\n grant = data as GrantFile;\n } else {\n throw new GrantValidationError(\"Invalid grant file schema\");\n }\n } catch (error) {\n if (error instanceof GrantValidationError) {\n const schemaError = new GrantSchemaError(\n error.message,\n Array.isArray(error.details?.errors) ? error.details.errors : [],\n data,\n );\n errors.push({\n type: \"schema\",\n message: error.message,\n error: schemaError,\n });\n } else {\n errors.push({\n type: \"schema\",\n message: `Schema validation failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error: error instanceof Error ? error : new Error(\"Unknown error\"),\n });\n }\n }\n } else {\n // Minimal type assertion if schema validation is skipped\n grant = data as GrantFile;\n }\n\n // 2. Business Logic Validation (only if we have a valid grant)\n if (grant) {\n // Check grantee access\n if (grantee) {\n try {\n validateGranteeAccess(grant, grantee);\n } catch (error) {\n const field = extractFieldFromBusinessError(error);\n errors.push({\n type: \"business\",\n field,\n message:\n error instanceof Error\n ? error.message\n : \"Unknown business rule error\",\n error: error instanceof Error ? error : new Error(\"Unknown error\"),\n });\n }\n }\n\n // Check expiration\n try {\n validateGrantExpiry(grant, currentTime);\n } catch (error) {\n const field = extractFieldFromBusinessError(error);\n errors.push({\n type: \"business\",\n field,\n message:\n error instanceof Error\n ? error.message\n : \"Unknown business rule error\",\n error: error instanceof Error ? error : new Error(\"Unknown error\"),\n });\n }\n\n // Check operation access\n if (operation) {\n try {\n validateOperationAccess(grant, operation);\n } catch (error) {\n const field = extractFieldFromBusinessError(error);\n errors.push({\n type: \"business\",\n field,\n message:\n error instanceof Error\n ? error.message\n : \"Unknown business rule error\",\n error: error instanceof Error ? error : new Error(\"Unknown error\"),\n });\n }\n }\n }\n\n // 3. Return Results\n if (errors.length > 0) {\n if (throwOnError) {\n // Throw the most specific error we have\n const firstError = errors[0];\n if (firstError.error) {\n throw firstError.error;\n } else {\n const combinedMessage = errors.map((e) => e.message).join(\"; \");\n throw new GrantValidationError(\n `Grant validation failed: ${combinedMessage}`,\n { errors, data },\n );\n }\n }\n\n return { valid: false, errors, grant };\n }\n\n if (throwOnError) {\n return grant as GrantFile;\n } else {\n return { valid: true, errors: [], grant: grant as GrantFile };\n }\n}\n\n/**\n * Helper function to extract field name from business validation errors\n *\n * @param error - The validation error to extract field information from\n * @returns The field name associated with the error, or undefined if not applicable\n */\nfunction extractFieldFromBusinessError(error: unknown): string | undefined {\n if (error instanceof GrantExpiredError) return \"expires\";\n if (error instanceof GranteeMismatchError) return \"grantee\";\n if (error instanceof OperationNotAllowedError) return \"operation\";\n return undefined;\n}\n\n/**\n * Validates that a grant file allows access for a specific grantee\n *\n * @param grantFile - The grant file to validate access for\n * @param requestingAddress - The address requesting access to check against the grantee\n */\nexport function validateGranteeAccess(\n grantFile: GrantFile,\n requestingAddress: Address,\n): void {\n const normalizedGrantee = getAddress(grantFile.grantee);\n const normalizedRequesting = getAddress(requestingAddress);\n\n if (normalizedGrantee !== normalizedRequesting) {\n throw new GranteeMismatchError(\n \"Permission denied: requesting address does not match grantee\",\n grantFile.grantee,\n requestingAddress,\n );\n }\n}\n\n/**\n * Validates that a grant has not expired (if expiry is set)\n *\n * @param grantFile - The grant file to check expiration for\n * @param currentTime - Optional override for current time (Unix timestamp)\n */\nexport function validateGrantExpiry(\n grantFile: GrantFile,\n currentTime?: number,\n): void {\n if (grantFile.expires) {\n const now =\n currentTime !== undefined ? currentTime : Math.floor(Date.now() / 1000); // Current Unix timestamp\n\n if (now > grantFile.expires) {\n throw new GrantExpiredError(\n \"Permission denied: grant has expired\",\n grantFile.expires,\n now,\n );\n }\n }\n}\n\n/**\n * Validates that a grant allows a specific operation\n *\n * @param grantFile - The grant file to validate operation access for\n * @param requestedOperation - The operation being requested to validate against the grant\n */\nexport function validateOperationAccess(\n grantFile: GrantFile,\n requestedOperation: string,\n): void {\n if (grantFile.operation !== requestedOperation) {\n throw new OperationNotAllowedError(\n \"Permission denied: operation not allowed by grant\",\n grantFile.operation,\n requestedOperation,\n );\n }\n}\n"],"mappings":"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","names":[]}
@@ -54,7 +54,7 @@ async function retrieveAndValidateGrant(grantUrl, relayerUrl) {
54
54
  const grantFile = await (0, import_grantFiles.retrieveGrantFile)(grantUrl, relayerUrl);
55
55
  return grantFile;
56
56
  }
57
- async function checkGrantAccess(grantUrl, requestingAddress, operation, fileIds, relayerUrl) {
57
+ async function checkGrantAccess(grantUrl, requestingAddress, operation, _fileIds, relayerUrl) {
58
58
  try {
59
59
  const grantFile = await retrieveAndValidateGrant(grantUrl, relayerUrl);
60
60
  (0, import_grantValidation.validateGrant)(grantFile, {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/grants.ts"],"sourcesContent":["import { Address } from \"viem\";\nimport type { GrantFile, GrantPermissionParams } from \"../types/permissions\";\nimport {\n createGrantFile,\n storeGrantFile,\n retrieveGrantFile,\n} from \"./grantFiles\";\nimport { validateGrant, GrantValidationError } from \"./grantValidation\";\n\n/**\n * High-level utilities for working with grants in the Vana SDK\n */\n\n/**\n * Creates and validates a grant file from permission parameters\n *\n * @param params - The permission parameters to create and validate the grant from\n * @returns The validated grant file object\n */\nexport function createValidatedGrant(params: GrantPermissionParams): GrantFile {\n const grantFile = createGrantFile(params);\n\n // Validate the created grant file\n try {\n validateGrant(grantFile, {\n schema: true,\n grantee: params.grantee,\n operation: params.operation,\n });\n } catch (error) {\n throw new GrantValidationError(\n `Created grant file failed validation: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n { grantFile, params },\n );\n }\n\n return grantFile;\n}\n\n/**\n * Creates a grant file and stores it in IPFS\n *\n * @param params - The permission parameters to create the grant from\n * @param relayerUrl - The URL of the relayer service for IPFS storage\n * @returns Promise resolving to an object containing the grant file and its IPFS URL\n */\nexport async function createAndStoreGrant(\n params: GrantPermissionParams,\n relayerUrl: string,\n): Promise<{ grantFile: GrantFile; grantUrl: string }> {\n const grantFile = createValidatedGrant(params);\n const grantUrl = await storeGrantFile(grantFile, relayerUrl);\n\n return { grantFile, grantUrl };\n}\n\n/**\n * Retrieves and validates a grant file from IPFS\n *\n * @param grantUrl - The IPFS URL of the grant file to retrieve\n * @param relayerUrl - Optional URL of the relayer service\n * @returns Promise resolving to the validated grant file\n */\nexport async function retrieveAndValidateGrant(\n grantUrl: string,\n relayerUrl?: string,\n): Promise<GrantFile> {\n const grantFile = await retrieveGrantFile(grantUrl, relayerUrl);\n\n // Additional validation can be added here if needed\n return grantFile;\n}\n\n/**\n * Checks if a grant allows access for a specific request\n *\n * @param grantUrl - The IPFS URL of the grant file to check\n * @param requestingAddress - The address making the access request\n * @param operation - The operation being requested\n * @param fileIds - Array of file IDs being accessed (currently unused but part of interface)\n * @param relayerUrl - Optional URL of the relayer service\n * @returns Promise resolving to access result with allowed status, reason, and grant file\n */\nexport async function checkGrantAccess(\n grantUrl: string,\n requestingAddress: Address,\n operation: string,\n fileIds: number[],\n relayerUrl?: string,\n): Promise<{ allowed: boolean; reason?: string; grantFile?: GrantFile }> {\n try {\n const grantFile = await retrieveAndValidateGrant(grantUrl, relayerUrl);\n\n // Validate the grant for the request\n validateGrant(grantFile, {\n schema: true,\n grantee: requestingAddress,\n operation,\n });\n\n return { allowed: true, grantFile };\n } catch (error) {\n if (error instanceof GrantValidationError) {\n return {\n allowed: false,\n reason: error.message,\n };\n }\n\n return {\n allowed: false,\n reason: `Grant access check failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n };\n }\n}\n\n/**\n * Utility to check if a grant has expired\n *\n * @param grantFile - The grant file to check for expiration\n * @returns True if the grant has expired, false otherwise\n */\nexport function isGrantExpired(grantFile: GrantFile): boolean {\n if (!grantFile.expires) {\n return false; // No expiration set\n }\n\n const now = Math.floor(Date.now() / 1000);\n return now > grantFile.expires;\n}\n\n/**\n * Utility to get the time remaining before grant expires (in seconds)\n *\n * @param grantFile - The grant file to check time remaining for\n * @returns Number of seconds remaining, or null if no expiration is set\n */\nexport function getGrantTimeRemaining(grantFile: GrantFile): number | null {\n if (!grantFile.expires) {\n return null; // No expiration set\n }\n\n const now = Math.floor(Date.now() / 1000);\n const remaining = grantFile.expires - now;\n return Math.max(0, remaining);\n}\n\n/**\n * Creates a human-readable summary of a grant\n *\n * @param grantFile - The grant file to create a summary for\n * @returns A human-readable string describing the grant\n */\nexport function summarizeGrant(grantFile: GrantFile): string {\n const expiration = grantFile.expires\n ? new Date(grantFile.expires * 1000).toISOString()\n : \"No expiration\";\n\n return `Grant for ${grantFile.grantee} to perform \"${grantFile.operation}\" (expires: ${expiration})`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,wBAIO;AACP,6BAAoD;AAY7C,SAAS,qBAAqB,QAA0C;AAC7E,QAAM,gBAAY,mCAAgB,MAAM;AAGxC,MAAI;AACF,8CAAc,WAAW;AAAA,MACvB,QAAQ;AAAA,MACR,SAAS,OAAO;AAAA,MAChB,WAAW,OAAO;AAAA,IACpB,CAAC;AAAA,EACH,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,yCAAyC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MACjG,EAAE,WAAW,OAAO;AAAA,IACtB;AAAA,EACF;AAEA,SAAO;AACT;AASA,eAAsB,oBACpB,QACA,YACqD;AACrD,QAAM,YAAY,qBAAqB,MAAM;AAC7C,QAAM,WAAW,UAAM,kCAAe,WAAW,UAAU;AAE3D,SAAO,EAAE,WAAW,SAAS;AAC/B;AASA,eAAsB,yBACpB,UACA,YACoB;AACpB,QAAM,YAAY,UAAM,qCAAkB,UAAU,UAAU;AAG9D,SAAO;AACT;AAYA,eAAsB,iBACpB,UACA,mBACA,WACA,SACA,YACuE;AACvE,MAAI;AACF,UAAM,YAAY,MAAM,yBAAyB,UAAU,UAAU;AAGrE,8CAAc,WAAW;AAAA,MACvB,QAAQ;AAAA,MACR,SAAS;AAAA,MACT;AAAA,IACF,CAAC;AAED,WAAO,EAAE,SAAS,MAAM,UAAU;AAAA,EACpC,SAAS,OAAO;AACd,QAAI,iBAAiB,6CAAsB;AACzC,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,MAAM;AAAA,MAChB;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,8BAA8B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,IAChG;AAAA,EACF;AACF;AAQO,SAAS,eAAe,WAA+B;AAC5D,MAAI,CAAC,UAAU,SAAS;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,SAAO,MAAM,UAAU;AACzB;AAQO,SAAS,sBAAsB,WAAqC;AACzE,MAAI,CAAC,UAAU,SAAS;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,QAAM,YAAY,UAAU,UAAU;AACtC,SAAO,KAAK,IAAI,GAAG,SAAS;AAC9B;AAQO,SAAS,eAAe,WAA8B;AAC3D,QAAM,aAAa,UAAU,UACzB,IAAI,KAAK,UAAU,UAAU,GAAI,EAAE,YAAY,IAC/C;AAEJ,SAAO,aAAa,UAAU,OAAO,gBAAgB,UAAU,SAAS,eAAe,UAAU;AACnG;","names":[]}
1
+ {"version":3,"sources":["../../src/utils/grants.ts"],"sourcesContent":["import type { Address } from \"viem\";\nimport type { GrantFile, GrantPermissionParams } from \"../types/permissions\";\nimport {\n createGrantFile,\n storeGrantFile,\n retrieveGrantFile,\n} from \"./grantFiles\";\nimport { validateGrant, GrantValidationError } from \"./grantValidation\";\n\n/**\n * High-level utilities for working with grants in the Vana SDK\n */\n\n/**\n * Creates and validates a grant file from permission parameters\n *\n * @param params - The permission parameters to create and validate the grant from\n * @returns The validated grant file object\n */\nexport function createValidatedGrant(params: GrantPermissionParams): GrantFile {\n const grantFile = createGrantFile(params);\n\n // Validate the created grant file\n try {\n validateGrant(grantFile, {\n schema: true,\n grantee: params.grantee,\n operation: params.operation,\n });\n } catch (error) {\n throw new GrantValidationError(\n `Created grant file failed validation: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n { grantFile, params },\n );\n }\n\n return grantFile;\n}\n\n/**\n * Creates a grant file and stores it in IPFS\n *\n * @param params - The permission parameters to create the grant from\n * @param relayerUrl - The URL of the relayer service for IPFS storage\n * @returns Promise resolving to an object containing the grant file and its IPFS URL\n */\nexport async function createAndStoreGrant(\n params: GrantPermissionParams,\n relayerUrl: string,\n): Promise<{ grantFile: GrantFile; grantUrl: string }> {\n const grantFile = createValidatedGrant(params);\n const grantUrl = await storeGrantFile(grantFile, relayerUrl);\n\n return { grantFile, grantUrl };\n}\n\n/**\n * Retrieves and validates a grant file from IPFS\n *\n * @param grantUrl - The IPFS URL of the grant file to retrieve\n * @param relayerUrl - Optional URL of the relayer service\n * @returns Promise resolving to the validated grant file\n */\nexport async function retrieveAndValidateGrant(\n grantUrl: string,\n relayerUrl?: string,\n): Promise<GrantFile> {\n const grantFile = await retrieveGrantFile(grantUrl, relayerUrl);\n\n // Additional validation can be added here if needed\n return grantFile;\n}\n\n/**\n * Checks if a grant allows access for a specific request\n *\n * @param grantUrl - The IPFS URL of the grant file to check\n * @param requestingAddress - The address making the access request\n * @param operation - The operation being requested\n * @param _fileIds - Array of file IDs being accessed (currently unused but part of interface)\n * @param relayerUrl - Optional URL of the relayer service\n * @returns Promise resolving to access result with allowed status, reason, and grant file\n */\nexport async function checkGrantAccess(\n grantUrl: string,\n requestingAddress: Address,\n operation: string,\n _fileIds: number[],\n relayerUrl?: string,\n): Promise<{ allowed: boolean; reason?: string; grantFile?: GrantFile }> {\n try {\n const grantFile = await retrieveAndValidateGrant(grantUrl, relayerUrl);\n\n // Validate the grant for the request\n validateGrant(grantFile, {\n schema: true,\n grantee: requestingAddress,\n operation,\n });\n\n return { allowed: true, grantFile };\n } catch (error) {\n if (error instanceof GrantValidationError) {\n return {\n allowed: false,\n reason: error.message,\n };\n }\n\n return {\n allowed: false,\n reason: `Grant access check failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n };\n }\n}\n\n/**\n * Utility to check if a grant has expired\n *\n * @param grantFile - The grant file to check for expiration\n * @returns True if the grant has expired, false otherwise\n */\nexport function isGrantExpired(grantFile: GrantFile): boolean {\n if (!grantFile.expires) {\n return false; // No expiration set\n }\n\n const now = Math.floor(Date.now() / 1000);\n return now > grantFile.expires;\n}\n\n/**\n * Utility to get the time remaining before grant expires (in seconds)\n *\n * @param grantFile - The grant file to check time remaining for\n * @returns Number of seconds remaining, or null if no expiration is set\n */\nexport function getGrantTimeRemaining(grantFile: GrantFile): number | null {\n if (!grantFile.expires) {\n return null; // No expiration set\n }\n\n const now = Math.floor(Date.now() / 1000);\n const remaining = grantFile.expires - now;\n return Math.max(0, remaining);\n}\n\n/**\n * Creates a human-readable summary of a grant\n *\n * @param grantFile - The grant file to create a summary for\n * @returns A human-readable string describing the grant\n */\nexport function summarizeGrant(grantFile: GrantFile): string {\n const expiration = grantFile.expires\n ? new Date(grantFile.expires * 1000).toISOString()\n : \"No expiration\";\n\n return `Grant for ${grantFile.grantee} to perform \"${grantFile.operation}\" (expires: ${expiration})`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,wBAIO;AACP,6BAAoD;AAY7C,SAAS,qBAAqB,QAA0C;AAC7E,QAAM,gBAAY,mCAAgB,MAAM;AAGxC,MAAI;AACF,8CAAc,WAAW;AAAA,MACvB,QAAQ;AAAA,MACR,SAAS,OAAO;AAAA,MAChB,WAAW,OAAO;AAAA,IACpB,CAAC;AAAA,EACH,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,yCAAyC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MACjG,EAAE,WAAW,OAAO;AAAA,IACtB;AAAA,EACF;AAEA,SAAO;AACT;AASA,eAAsB,oBACpB,QACA,YACqD;AACrD,QAAM,YAAY,qBAAqB,MAAM;AAC7C,QAAM,WAAW,UAAM,kCAAe,WAAW,UAAU;AAE3D,SAAO,EAAE,WAAW,SAAS;AAC/B;AASA,eAAsB,yBACpB,UACA,YACoB;AACpB,QAAM,YAAY,UAAM,qCAAkB,UAAU,UAAU;AAG9D,SAAO;AACT;AAYA,eAAsB,iBACpB,UACA,mBACA,WACA,UACA,YACuE;AACvE,MAAI;AACF,UAAM,YAAY,MAAM,yBAAyB,UAAU,UAAU;AAGrE,8CAAc,WAAW;AAAA,MACvB,QAAQ;AAAA,MACR,SAAS;AAAA,MACT;AAAA,IACF,CAAC;AAED,WAAO,EAAE,SAAS,MAAM,UAAU;AAAA,EACpC,SAAS,OAAO;AACd,QAAI,iBAAiB,6CAAsB;AACzC,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,MAAM;AAAA,MAChB;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,8BAA8B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,IAChG;AAAA,EACF;AACF;AAQO,SAAS,eAAe,WAA+B;AAC5D,MAAI,CAAC,UAAU,SAAS;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,SAAO,MAAM,UAAU;AACzB;AAQO,SAAS,sBAAsB,WAAqC;AACzE,MAAI,CAAC,UAAU,SAAS;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,QAAM,YAAY,UAAU,UAAU;AACtC,SAAO,KAAK,IAAI,GAAG,SAAS;AAC9B;AAQO,SAAS,eAAe,WAA8B;AAC3D,QAAM,aAAa,UAAU,UACzB,IAAI,KAAK,UAAU,UAAU,GAAI,EAAE,YAAY,IAC/C;AAEJ,SAAO,aAAa,UAAU,OAAO,gBAAgB,UAAU,SAAS,eAAe,UAAU;AACnG;","names":[]}
@@ -1,6 +1,5 @@
1
- import { Address } from 'viem';
2
- import { GrantPermissionParams, GrantFile } from '../types/permissions.js';
3
-
1
+ import type { Address } from "viem";
2
+ import type { GrantFile, GrantPermissionParams } from "../types/permissions";
4
3
  /**
5
4
  * High-level utilities for working with grants in the Vana SDK
6
5
  */
@@ -10,7 +9,7 @@ import { GrantPermissionParams, GrantFile } from '../types/permissions.js';
10
9
  * @param params - The permission parameters to create and validate the grant from
11
10
  * @returns The validated grant file object
12
11
  */
13
- declare function createValidatedGrant(params: GrantPermissionParams): GrantFile;
12
+ export declare function createValidatedGrant(params: GrantPermissionParams): GrantFile;
14
13
  /**
15
14
  * Creates a grant file and stores it in IPFS
16
15
  *
@@ -18,7 +17,7 @@ declare function createValidatedGrant(params: GrantPermissionParams): GrantFile;
18
17
  * @param relayerUrl - The URL of the relayer service for IPFS storage
19
18
  * @returns Promise resolving to an object containing the grant file and its IPFS URL
20
19
  */
21
- declare function createAndStoreGrant(params: GrantPermissionParams, relayerUrl: string): Promise<{
20
+ export declare function createAndStoreGrant(params: GrantPermissionParams, relayerUrl: string): Promise<{
22
21
  grantFile: GrantFile;
23
22
  grantUrl: string;
24
23
  }>;
@@ -29,18 +28,18 @@ declare function createAndStoreGrant(params: GrantPermissionParams, relayerUrl:
29
28
  * @param relayerUrl - Optional URL of the relayer service
30
29
  * @returns Promise resolving to the validated grant file
31
30
  */
32
- declare function retrieveAndValidateGrant(grantUrl: string, relayerUrl?: string): Promise<GrantFile>;
31
+ export declare function retrieveAndValidateGrant(grantUrl: string, relayerUrl?: string): Promise<GrantFile>;
33
32
  /**
34
33
  * Checks if a grant allows access for a specific request
35
34
  *
36
35
  * @param grantUrl - The IPFS URL of the grant file to check
37
36
  * @param requestingAddress - The address making the access request
38
37
  * @param operation - The operation being requested
39
- * @param fileIds - Array of file IDs being accessed (currently unused but part of interface)
38
+ * @param _fileIds - Array of file IDs being accessed (currently unused but part of interface)
40
39
  * @param relayerUrl - Optional URL of the relayer service
41
40
  * @returns Promise resolving to access result with allowed status, reason, and grant file
42
41
  */
43
- declare function checkGrantAccess(grantUrl: string, requestingAddress: Address, operation: string, fileIds: number[], relayerUrl?: string): Promise<{
42
+ export declare function checkGrantAccess(grantUrl: string, requestingAddress: Address, operation: string, _fileIds: number[], relayerUrl?: string): Promise<{
44
43
  allowed: boolean;
45
44
  reason?: string;
46
45
  grantFile?: GrantFile;
@@ -51,20 +50,18 @@ declare function checkGrantAccess(grantUrl: string, requestingAddress: Address,
51
50
  * @param grantFile - The grant file to check for expiration
52
51
  * @returns True if the grant has expired, false otherwise
53
52
  */
54
- declare function isGrantExpired(grantFile: GrantFile): boolean;
53
+ export declare function isGrantExpired(grantFile: GrantFile): boolean;
55
54
  /**
56
55
  * Utility to get the time remaining before grant expires (in seconds)
57
56
  *
58
57
  * @param grantFile - The grant file to check time remaining for
59
58
  * @returns Number of seconds remaining, or null if no expiration is set
60
59
  */
61
- declare function getGrantTimeRemaining(grantFile: GrantFile): number | null;
60
+ export declare function getGrantTimeRemaining(grantFile: GrantFile): number | null;
62
61
  /**
63
62
  * Creates a human-readable summary of a grant
64
63
  *
65
64
  * @param grantFile - The grant file to create a summary for
66
65
  * @returns A human-readable string describing the grant
67
66
  */
68
- declare function summarizeGrant(grantFile: GrantFile): string;
69
-
70
- export { checkGrantAccess, createAndStoreGrant, createValidatedGrant, getGrantTimeRemaining, isGrantExpired, retrieveAndValidateGrant, summarizeGrant };
67
+ export declare function summarizeGrant(grantFile: GrantFile): string;
@@ -29,7 +29,7 @@ async function retrieveAndValidateGrant(grantUrl, relayerUrl) {
29
29
  const grantFile = await retrieveGrantFile(grantUrl, relayerUrl);
30
30
  return grantFile;
31
31
  }
32
- async function checkGrantAccess(grantUrl, requestingAddress, operation, fileIds, relayerUrl) {
32
+ async function checkGrantAccess(grantUrl, requestingAddress, operation, _fileIds, relayerUrl) {
33
33
  try {
34
34
  const grantFile = await retrieveAndValidateGrant(grantUrl, relayerUrl);
35
35
  validateGrant(grantFile, {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/grants.ts"],"sourcesContent":["import { Address } from \"viem\";\nimport type { GrantFile, GrantPermissionParams } from \"../types/permissions\";\nimport {\n createGrantFile,\n storeGrantFile,\n retrieveGrantFile,\n} from \"./grantFiles\";\nimport { validateGrant, GrantValidationError } from \"./grantValidation\";\n\n/**\n * High-level utilities for working with grants in the Vana SDK\n */\n\n/**\n * Creates and validates a grant file from permission parameters\n *\n * @param params - The permission parameters to create and validate the grant from\n * @returns The validated grant file object\n */\nexport function createValidatedGrant(params: GrantPermissionParams): GrantFile {\n const grantFile = createGrantFile(params);\n\n // Validate the created grant file\n try {\n validateGrant(grantFile, {\n schema: true,\n grantee: params.grantee,\n operation: params.operation,\n });\n } catch (error) {\n throw new GrantValidationError(\n `Created grant file failed validation: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n { grantFile, params },\n );\n }\n\n return grantFile;\n}\n\n/**\n * Creates a grant file and stores it in IPFS\n *\n * @param params - The permission parameters to create the grant from\n * @param relayerUrl - The URL of the relayer service for IPFS storage\n * @returns Promise resolving to an object containing the grant file and its IPFS URL\n */\nexport async function createAndStoreGrant(\n params: GrantPermissionParams,\n relayerUrl: string,\n): Promise<{ grantFile: GrantFile; grantUrl: string }> {\n const grantFile = createValidatedGrant(params);\n const grantUrl = await storeGrantFile(grantFile, relayerUrl);\n\n return { grantFile, grantUrl };\n}\n\n/**\n * Retrieves and validates a grant file from IPFS\n *\n * @param grantUrl - The IPFS URL of the grant file to retrieve\n * @param relayerUrl - Optional URL of the relayer service\n * @returns Promise resolving to the validated grant file\n */\nexport async function retrieveAndValidateGrant(\n grantUrl: string,\n relayerUrl?: string,\n): Promise<GrantFile> {\n const grantFile = await retrieveGrantFile(grantUrl, relayerUrl);\n\n // Additional validation can be added here if needed\n return grantFile;\n}\n\n/**\n * Checks if a grant allows access for a specific request\n *\n * @param grantUrl - The IPFS URL of the grant file to check\n * @param requestingAddress - The address making the access request\n * @param operation - The operation being requested\n * @param fileIds - Array of file IDs being accessed (currently unused but part of interface)\n * @param relayerUrl - Optional URL of the relayer service\n * @returns Promise resolving to access result with allowed status, reason, and grant file\n */\nexport async function checkGrantAccess(\n grantUrl: string,\n requestingAddress: Address,\n operation: string,\n fileIds: number[],\n relayerUrl?: string,\n): Promise<{ allowed: boolean; reason?: string; grantFile?: GrantFile }> {\n try {\n const grantFile = await retrieveAndValidateGrant(grantUrl, relayerUrl);\n\n // Validate the grant for the request\n validateGrant(grantFile, {\n schema: true,\n grantee: requestingAddress,\n operation,\n });\n\n return { allowed: true, grantFile };\n } catch (error) {\n if (error instanceof GrantValidationError) {\n return {\n allowed: false,\n reason: error.message,\n };\n }\n\n return {\n allowed: false,\n reason: `Grant access check failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n };\n }\n}\n\n/**\n * Utility to check if a grant has expired\n *\n * @param grantFile - The grant file to check for expiration\n * @returns True if the grant has expired, false otherwise\n */\nexport function isGrantExpired(grantFile: GrantFile): boolean {\n if (!grantFile.expires) {\n return false; // No expiration set\n }\n\n const now = Math.floor(Date.now() / 1000);\n return now > grantFile.expires;\n}\n\n/**\n * Utility to get the time remaining before grant expires (in seconds)\n *\n * @param grantFile - The grant file to check time remaining for\n * @returns Number of seconds remaining, or null if no expiration is set\n */\nexport function getGrantTimeRemaining(grantFile: GrantFile): number | null {\n if (!grantFile.expires) {\n return null; // No expiration set\n }\n\n const now = Math.floor(Date.now() / 1000);\n const remaining = grantFile.expires - now;\n return Math.max(0, remaining);\n}\n\n/**\n * Creates a human-readable summary of a grant\n *\n * @param grantFile - The grant file to create a summary for\n * @returns A human-readable string describing the grant\n */\nexport function summarizeGrant(grantFile: GrantFile): string {\n const expiration = grantFile.expires\n ? new Date(grantFile.expires * 1000).toISOString()\n : \"No expiration\";\n\n return `Grant for ${grantFile.grantee} to perform \"${grantFile.operation}\" (expires: ${expiration})`;\n}\n"],"mappings":"AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,eAAe,4BAA4B;AAY7C,SAAS,qBAAqB,QAA0C;AAC7E,QAAM,YAAY,gBAAgB,MAAM;AAGxC,MAAI;AACF,kBAAc,WAAW;AAAA,MACvB,QAAQ;AAAA,MACR,SAAS,OAAO;AAAA,MAChB,WAAW,OAAO;AAAA,IACpB,CAAC;AAAA,EACH,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,yCAAyC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MACjG,EAAE,WAAW,OAAO;AAAA,IACtB;AAAA,EACF;AAEA,SAAO;AACT;AASA,eAAsB,oBACpB,QACA,YACqD;AACrD,QAAM,YAAY,qBAAqB,MAAM;AAC7C,QAAM,WAAW,MAAM,eAAe,WAAW,UAAU;AAE3D,SAAO,EAAE,WAAW,SAAS;AAC/B;AASA,eAAsB,yBACpB,UACA,YACoB;AACpB,QAAM,YAAY,MAAM,kBAAkB,UAAU,UAAU;AAG9D,SAAO;AACT;AAYA,eAAsB,iBACpB,UACA,mBACA,WACA,SACA,YACuE;AACvE,MAAI;AACF,UAAM,YAAY,MAAM,yBAAyB,UAAU,UAAU;AAGrE,kBAAc,WAAW;AAAA,MACvB,QAAQ;AAAA,MACR,SAAS;AAAA,MACT;AAAA,IACF,CAAC;AAED,WAAO,EAAE,SAAS,MAAM,UAAU;AAAA,EACpC,SAAS,OAAO;AACd,QAAI,iBAAiB,sBAAsB;AACzC,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,MAAM;AAAA,MAChB;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,8BAA8B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,IAChG;AAAA,EACF;AACF;AAQO,SAAS,eAAe,WAA+B;AAC5D,MAAI,CAAC,UAAU,SAAS;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,SAAO,MAAM,UAAU;AACzB;AAQO,SAAS,sBAAsB,WAAqC;AACzE,MAAI,CAAC,UAAU,SAAS;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,QAAM,YAAY,UAAU,UAAU;AACtC,SAAO,KAAK,IAAI,GAAG,SAAS;AAC9B;AAQO,SAAS,eAAe,WAA8B;AAC3D,QAAM,aAAa,UAAU,UACzB,IAAI,KAAK,UAAU,UAAU,GAAI,EAAE,YAAY,IAC/C;AAEJ,SAAO,aAAa,UAAU,OAAO,gBAAgB,UAAU,SAAS,eAAe,UAAU;AACnG;","names":[]}
1
+ {"version":3,"sources":["../../src/utils/grants.ts"],"sourcesContent":["import type { Address } from \"viem\";\nimport type { GrantFile, GrantPermissionParams } from \"../types/permissions\";\nimport {\n createGrantFile,\n storeGrantFile,\n retrieveGrantFile,\n} from \"./grantFiles\";\nimport { validateGrant, GrantValidationError } from \"./grantValidation\";\n\n/**\n * High-level utilities for working with grants in the Vana SDK\n */\n\n/**\n * Creates and validates a grant file from permission parameters\n *\n * @param params - The permission parameters to create and validate the grant from\n * @returns The validated grant file object\n */\nexport function createValidatedGrant(params: GrantPermissionParams): GrantFile {\n const grantFile = createGrantFile(params);\n\n // Validate the created grant file\n try {\n validateGrant(grantFile, {\n schema: true,\n grantee: params.grantee,\n operation: params.operation,\n });\n } catch (error) {\n throw new GrantValidationError(\n `Created grant file failed validation: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n { grantFile, params },\n );\n }\n\n return grantFile;\n}\n\n/**\n * Creates a grant file and stores it in IPFS\n *\n * @param params - The permission parameters to create the grant from\n * @param relayerUrl - The URL of the relayer service for IPFS storage\n * @returns Promise resolving to an object containing the grant file and its IPFS URL\n */\nexport async function createAndStoreGrant(\n params: GrantPermissionParams,\n relayerUrl: string,\n): Promise<{ grantFile: GrantFile; grantUrl: string }> {\n const grantFile = createValidatedGrant(params);\n const grantUrl = await storeGrantFile(grantFile, relayerUrl);\n\n return { grantFile, grantUrl };\n}\n\n/**\n * Retrieves and validates a grant file from IPFS\n *\n * @param grantUrl - The IPFS URL of the grant file to retrieve\n * @param relayerUrl - Optional URL of the relayer service\n * @returns Promise resolving to the validated grant file\n */\nexport async function retrieveAndValidateGrant(\n grantUrl: string,\n relayerUrl?: string,\n): Promise<GrantFile> {\n const grantFile = await retrieveGrantFile(grantUrl, relayerUrl);\n\n // Additional validation can be added here if needed\n return grantFile;\n}\n\n/**\n * Checks if a grant allows access for a specific request\n *\n * @param grantUrl - The IPFS URL of the grant file to check\n * @param requestingAddress - The address making the access request\n * @param operation - The operation being requested\n * @param _fileIds - Array of file IDs being accessed (currently unused but part of interface)\n * @param relayerUrl - Optional URL of the relayer service\n * @returns Promise resolving to access result with allowed status, reason, and grant file\n */\nexport async function checkGrantAccess(\n grantUrl: string,\n requestingAddress: Address,\n operation: string,\n _fileIds: number[],\n relayerUrl?: string,\n): Promise<{ allowed: boolean; reason?: string; grantFile?: GrantFile }> {\n try {\n const grantFile = await retrieveAndValidateGrant(grantUrl, relayerUrl);\n\n // Validate the grant for the request\n validateGrant(grantFile, {\n schema: true,\n grantee: requestingAddress,\n operation,\n });\n\n return { allowed: true, grantFile };\n } catch (error) {\n if (error instanceof GrantValidationError) {\n return {\n allowed: false,\n reason: error.message,\n };\n }\n\n return {\n allowed: false,\n reason: `Grant access check failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n };\n }\n}\n\n/**\n * Utility to check if a grant has expired\n *\n * @param grantFile - The grant file to check for expiration\n * @returns True if the grant has expired, false otherwise\n */\nexport function isGrantExpired(grantFile: GrantFile): boolean {\n if (!grantFile.expires) {\n return false; // No expiration set\n }\n\n const now = Math.floor(Date.now() / 1000);\n return now > grantFile.expires;\n}\n\n/**\n * Utility to get the time remaining before grant expires (in seconds)\n *\n * @param grantFile - The grant file to check time remaining for\n * @returns Number of seconds remaining, or null if no expiration is set\n */\nexport function getGrantTimeRemaining(grantFile: GrantFile): number | null {\n if (!grantFile.expires) {\n return null; // No expiration set\n }\n\n const now = Math.floor(Date.now() / 1000);\n const remaining = grantFile.expires - now;\n return Math.max(0, remaining);\n}\n\n/**\n * Creates a human-readable summary of a grant\n *\n * @param grantFile - The grant file to create a summary for\n * @returns A human-readable string describing the grant\n */\nexport function summarizeGrant(grantFile: GrantFile): string {\n const expiration = grantFile.expires\n ? new Date(grantFile.expires * 1000).toISOString()\n : \"No expiration\";\n\n return `Grant for ${grantFile.grantee} to perform \"${grantFile.operation}\" (expires: ${expiration})`;\n}\n"],"mappings":"AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,eAAe,4BAA4B;AAY7C,SAAS,qBAAqB,QAA0C;AAC7E,QAAM,YAAY,gBAAgB,MAAM;AAGxC,MAAI;AACF,kBAAc,WAAW;AAAA,MACvB,QAAQ;AAAA,MACR,SAAS,OAAO;AAAA,MAChB,WAAW,OAAO;AAAA,IACpB,CAAC;AAAA,EACH,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,yCAAyC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MACjG,EAAE,WAAW,OAAO;AAAA,IACtB;AAAA,EACF;AAEA,SAAO;AACT;AASA,eAAsB,oBACpB,QACA,YACqD;AACrD,QAAM,YAAY,qBAAqB,MAAM;AAC7C,QAAM,WAAW,MAAM,eAAe,WAAW,UAAU;AAE3D,SAAO,EAAE,WAAW,SAAS;AAC/B;AASA,eAAsB,yBACpB,UACA,YACoB;AACpB,QAAM,YAAY,MAAM,kBAAkB,UAAU,UAAU;AAG9D,SAAO;AACT;AAYA,eAAsB,iBACpB,UACA,mBACA,WACA,UACA,YACuE;AACvE,MAAI;AACF,UAAM,YAAY,MAAM,yBAAyB,UAAU,UAAU;AAGrE,kBAAc,WAAW;AAAA,MACvB,QAAQ;AAAA,MACR,SAAS;AAAA,MACT;AAAA,IACF,CAAC;AAED,WAAO,EAAE,SAAS,MAAM,UAAU;AAAA,EACpC,SAAS,OAAO;AACd,QAAI,iBAAiB,sBAAsB;AACzC,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,MAAM;AAAA,MAChB;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,8BAA8B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,IAChG;AAAA,EACF;AACF;AAQO,SAAS,eAAe,WAA+B;AAC5D,MAAI,CAAC,UAAU,SAAS;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,SAAO,MAAM,UAAU;AACzB;AAQO,SAAS,sBAAsB,WAAqC;AACzE,MAAI,CAAC,UAAU,SAAS;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,QAAM,YAAY,UAAU,UAAU;AACtC,SAAO,KAAK,IAAI,GAAG,SAAS;AAC9B;AAQO,SAAS,eAAe,WAA8B;AAC3D,QAAM,aAAa,UAAU,UACzB,IAAI,KAAK,UAAU,UAAU,GAAI,EAAE,YAAY,IAC/C;AAEJ,SAAO,aAAa,UAAU,OAAO,gBAAgB,UAAU,SAAS,eAAe,UAAU;AACnG;","names":[]}
@@ -7,18 +7,18 @@
7
7
  /**
8
8
  * Default IPFS gateway URL
9
9
  */
10
- declare const DEFAULT_IPFS_GATEWAY = "https://dweb.link/ipfs/";
10
+ export declare const DEFAULT_IPFS_GATEWAY = "https://dweb.link/ipfs/";
11
11
  /**
12
12
  * Alternative IPFS gateways for fallback - ordered by reliability and rate limits
13
13
  */
14
- declare const IPFS_GATEWAYS: readonly ["https://dweb.link/ipfs/", "https://ipfs.io/ipfs/", "https://cloudflare-ipfs.com/ipfs/", "https://gateway.pinata.cloud/ipfs/", "https://ipfs.filebase.io/ipfs/"];
14
+ export declare const IPFS_GATEWAYS: readonly ["https://dweb.link/ipfs/", "https://ipfs.io/ipfs/", "https://cloudflare-ipfs.com/ipfs/", "https://gateway.pinata.cloud/ipfs/", "https://ipfs.filebase.io/ipfs/"];
15
15
  /**
16
16
  * Check if a URL is an IPFS URL (starts with ipfs://)
17
17
  *
18
18
  * @param url - The URL to check
19
19
  * @returns True if the URL is an IPFS URL
20
20
  */
21
- declare function isIpfsUrl(url: string): boolean;
21
+ export declare function isIpfsUrl(url: string): boolean;
22
22
  /**
23
23
  * Convert an IPFS URL to an HTTP gateway URL
24
24
  *
@@ -34,7 +34,7 @@ declare function isIpfsUrl(url: string): boolean;
34
34
  * // Returns: "https://gateway.pinata.cloud/ipfs/QmHash123"
35
35
  * ```
36
36
  */
37
- declare function convertIpfsUrl(url: string, gateway?: string): string;
37
+ export declare function convertIpfsUrl(url: string, gateway?: string): string;
38
38
  /**
39
39
  * Extract IPFS hash from various URL formats
40
40
  *
@@ -55,21 +55,21 @@ declare function convertIpfsUrl(url: string, gateway?: string): string;
55
55
  * extractIpfsHash("ipfs://QmHash/subdirectory") // Returns: null (subdirectories not supported)
56
56
  * ```
57
57
  */
58
- declare function extractIpfsHash(url: string): string | null;
58
+ export declare function extractIpfsHash(url: string): string | null;
59
59
  /**
60
60
  * Get multiple gateway URLs for an IPFS hash (useful for fallback)
61
61
  *
62
62
  * @param hash - The IPFS hash
63
63
  * @returns Array of gateway URLs
64
64
  */
65
- declare function getGatewayUrls(hash: string): string[];
65
+ export declare function getGatewayUrls(hash: string): string[];
66
66
  /**
67
67
  * Convert an IPFS URL to multiple gateway URLs for fallback
68
68
  *
69
69
  * @param url - The IPFS URL
70
70
  * @returns Array of gateway URLs or original URL if not IPFS
71
71
  */
72
- declare function convertIpfsUrlWithFallbacks(url: string): string[];
72
+ export declare function convertIpfsUrlWithFallbacks(url: string): string[];
73
73
  /**
74
74
  * Fetch content from IPFS with automatic gateway fallbacks
75
75
  *
@@ -85,6 +85,4 @@ declare function convertIpfsUrlWithFallbacks(url: string): string[];
85
85
  * @returns Promise resolving to Response object
86
86
  * @throws Error if all gateways fail
87
87
  */
88
- declare function fetchWithFallbacks(url: string, options?: RequestInit): Promise<Response>;
89
-
90
- export { DEFAULT_IPFS_GATEWAY, IPFS_GATEWAYS, convertIpfsUrl, convertIpfsUrlWithFallbacks, extractIpfsHash, fetchWithFallbacks, getGatewayUrls, isIpfsUrl };
88
+ export declare function fetchWithFallbacks(url: string, options?: RequestInit): Promise<Response>;
@@ -24,12 +24,10 @@ module.exports = __toCommonJS(lazy_import_exports);
24
24
  function lazyImport(importFn) {
25
25
  let cached = null;
26
26
  return () => {
27
- if (!cached) {
28
- cached = importFn().catch((err) => {
29
- cached = null;
30
- throw new Error("Failed to load module", { cause: err });
31
- });
32
- }
27
+ cached ??= importFn().catch((err) => {
28
+ cached = null;
29
+ throw new Error("Failed to load module", { cause: err });
30
+ });
33
31
  return cached;
34
32
  };
35
33
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/lazy-import.ts"],"sourcesContent":["/**\n * Utility for lazy-loading modules to avoid Turbopack TDZ issues\n *\n * WARNING: This is a workaround for Turbopack's strict module initialization.\n * Dependencies that access globals during init must be dynamically imported.\n */\n\n/**\n * Creates a lazy import function that caches the promise (not the module)\n * to avoid race conditions on concurrent first calls\n *\n * @param importFn - Function that returns a dynamic import promise\n * @returns Function that returns the cached import promise\n *\n * @example\n * const getOpenPGP = lazyImport(() => import('openpgp'));\n * const openpgp = await getOpenPGP();\n */\nexport function lazyImport<T>(importFn: () => Promise<T>): () => Promise<T> {\n let cached: Promise<T> | null = null;\n\n return () => {\n if (!cached) {\n cached = importFn().catch((err) => {\n // Clear cache on error so next attempt can retry\n cached = null;\n throw new Error(\"Failed to load module\", { cause: err });\n });\n }\n return cached;\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBO,SAAS,WAAc,UAA8C;AAC1E,MAAI,SAA4B;AAEhC,SAAO,MAAM;AACX,QAAI,CAAC,QAAQ;AACX,eAAS,SAAS,EAAE,MAAM,CAAC,QAAQ;AAEjC,iBAAS;AACT,cAAM,IAAI,MAAM,yBAAyB,EAAE,OAAO,IAAI,CAAC;AAAA,MACzD,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/utils/lazy-import.ts"],"sourcesContent":["/**\n * Utility for lazy-loading modules to avoid Turbopack TDZ issues\n *\n * WARNING: This is a workaround for Turbopack's strict module initialization.\n * Dependencies that access globals during init must be dynamically imported.\n */\n\n/**\n * Creates a lazy import function that caches the promise (not the module)\n * to avoid race conditions on concurrent first calls\n *\n * @param importFn - Function that returns a dynamic import promise\n * @returns Function that returns the cached import promise\n *\n * @example\n * const getOpenPGP = lazyImport(() => import('openpgp'));\n * const openpgp = await getOpenPGP();\n */\nexport function lazyImport<T>(importFn: () => Promise<T>): () => Promise<T> {\n let cached: Promise<T> | null = null;\n\n return () => {\n cached ??= importFn().catch((err) => {\n // Clear cache on error so next attempt can retry\n cached = null;\n throw new Error(\"Failed to load module\", { cause: err });\n });\n return cached;\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBO,SAAS,WAAc,UAA8C;AAC1E,MAAI,SAA4B;AAEhC,SAAO,MAAM;AACX,eAAW,SAAS,EAAE,MAAM,CAAC,QAAQ;AAEnC,eAAS;AACT,YAAM,IAAI,MAAM,yBAAyB,EAAE,OAAO,IAAI,CAAC;AAAA,IACzD,CAAC;AACD,WAAO;AAAA,EACT;AACF;","names":[]}