@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/crypto/ecies/base.ts"],"sourcesContent":["import type { ECIESProvider, ECIESEncrypted } from \"./interface\";\nimport { ECIESError, isECIESEncrypted } from \"./interface\";\nimport { CURVE, CIPHER, KDF } from \"./constants\";\nimport { concatBytes, constantTimeEqual } from \"./utils\";\n\n/**\n * Provides shared ECIES encryption logic across platforms using Uint8Array.\n *\n * @remarks\n * Platform implementations extend this class and provide crypto primitives.\n * The base class handles the ECIES protocol flow while maintaining\n * compatibility with the eccrypto data format.\n *\n * **Implementation details:**\n * - KDF: SHA-512(shared_secret) → encKey (32B) || macKey (32B)\n * - Cipher: AES-256-CBC with random 16-byte IV\n * - MAC: HMAC-SHA256(macKey, iv || ephemPublicKey || ciphertext)\n *\n * @category Cryptography\n */\nexport abstract class BaseECIESUint8 implements ECIESProvider {\n // Cache for validated public keys to avoid repeated validation\n private static readonly validatedKeys = new WeakMap<Uint8Array, boolean>();\n\n /**\n * Generates cryptographically secure random bytes.\n *\n * @param length - Number of random bytes to generate.\n * @returns Random bytes array.\n */\n protected abstract generateRandomBytes(length: number): Uint8Array;\n\n /**\n * Verifies a private key is valid for secp256k1.\n *\n * @param privateKey - Private key to verify (32 bytes).\n * @returns `true` if valid private key.\n */\n protected abstract verifyPrivateKey(privateKey: Uint8Array): boolean;\n\n /**\n * Creates a public key from a private key.\n *\n * @param privateKey - Source private key (32 bytes).\n * @param compressed - Generate compressed (33B) or uncompressed (65B) format.\n * @returns Public key or `null` if creation failed.\n */\n protected abstract createPublicKey(\n privateKey: Uint8Array,\n compressed: boolean,\n ): Uint8Array | null;\n\n /**\n * Validates a public key on the secp256k1 curve.\n *\n * @param publicKey - Public key to validate.\n * @returns `true` if valid public key.\n */\n protected abstract validatePublicKey(publicKey: Uint8Array): boolean;\n\n /**\n * Decompresses a compressed public key.\n *\n * @param publicKey - Compressed public key (33 bytes).\n * @returns Uncompressed public key (65 bytes) or `null` if decompression failed.\n */\n protected abstract decompressPublicKey(\n publicKey: Uint8Array,\n ): Uint8Array | null;\n\n /**\n * Performs ECDH key agreement.\n *\n * @param publicKey - Other party's public key.\n * @param privateKey - Your private key.\n * @returns Raw X coordinate of shared point (32 bytes).\n */\n protected abstract performECDH(\n publicKey: Uint8Array,\n privateKey: Uint8Array,\n ): Uint8Array;\n\n /**\n * Computes SHA-512 hash.\n *\n * @param data - Data to hash.\n * @returns SHA-512 hash (64 bytes).\n */\n protected abstract sha512(data: Uint8Array): Uint8Array;\n\n /**\n * Computes HMAC-SHA256 authentication tag.\n *\n * @param key - HMAC key.\n * @param data - Data to authenticate.\n * @returns HMAC-SHA256 (32 bytes).\n */\n protected abstract hmacSha256(key: Uint8Array, data: Uint8Array): Uint8Array;\n\n /**\n * Encrypts data using AES-256-CBC.\n *\n * @param key - Encryption key (32 bytes).\n * @param iv - Initialization vector (16 bytes).\n * @param plaintext - Data to encrypt.\n * @returns Ciphertext with PKCS#7 padding.\n */\n protected abstract aesEncrypt(\n key: Uint8Array,\n iv: Uint8Array,\n plaintext: Uint8Array,\n ): Promise<Uint8Array>;\n\n /**\n * Decrypts data using AES-256-CBC.\n *\n * @param key - Decryption key (32 bytes).\n * @param iv - Initialization vector (16 bytes).\n * @param ciphertext - Data to decrypt.\n * @returns Plaintext with padding removed.\n */\n protected abstract aesDecrypt(\n key: Uint8Array,\n iv: Uint8Array,\n ciphertext: Uint8Array,\n ): Promise<Uint8Array>;\n\n /**\n * Normalizes a public key to uncompressed format.\n *\n * @param publicKey - Public key in any format.\n * @returns Uncompressed public key (65 bytes).\n * @throws {ECIESError} If key format is invalid.\n */\n protected normalizePublicKey(publicKey: Uint8Array): Uint8Array {\n // Check cache first\n if (BaseECIESUint8.validatedKeys.has(publicKey)) {\n return publicKey;\n }\n\n if (publicKey.length === CURVE.UNCOMPRESSED_PUBLIC_KEY_LENGTH) {\n if (publicKey[0] !== CURVE.PREFIX.UNCOMPRESSED) {\n throw new ECIESError(\n \"Invalid uncompressed public key prefix\",\n \"INVALID_KEY\",\n );\n }\n // Validate and cache\n if (!this.validatePublicKey(publicKey)) {\n throw new ECIESError(\"Invalid public key\", \"INVALID_KEY\");\n }\n BaseECIESUint8.validatedKeys.set(publicKey, true);\n return publicKey;\n }\n\n if (publicKey.length === CURVE.COMPRESSED_PUBLIC_KEY_LENGTH) {\n const decompressed = this.decompressPublicKey(publicKey);\n if (!decompressed) {\n throw new ECIESError(\"Failed to decompress public key\", \"INVALID_KEY\");\n }\n // Cache the decompressed key\n BaseECIESUint8.validatedKeys.set(decompressed, true);\n return decompressed;\n }\n\n throw new ECIESError(\n `Invalid public key length: ${publicKey.length}`,\n \"INVALID_KEY\",\n );\n }\n\n /**\n * Normalizes a public key to uncompressed format (65 bytes with 0x04 prefix).\n * Must be implemented by derived classes to handle platform-specific operations.\n *\n * @param publicKey - The public key to normalize\n * @returns The normalized uncompressed public key\n */\n public abstract normalizeToUncompressed(publicKey: Uint8Array): Uint8Array;\n\n /**\n * Encrypts data using ECIES.\n *\n * @param publicKey - The recipient's public key (compressed or uncompressed)\n * @param message - The data to encrypt\n * @returns Promise resolving to encrypted data structure\n */\n async encrypt(\n publicKey: Uint8Array,\n message: Uint8Array,\n ): Promise<ECIESEncrypted> {\n try {\n // Validate inputs\n if (!(publicKey instanceof Uint8Array)) {\n throw new ECIESError(\"Public key must be a Uint8Array\", \"INVALID_KEY\");\n }\n if (!(message instanceof Uint8Array)) {\n throw new ECIESError(\n \"Message must be a Uint8Array\",\n \"ENCRYPTION_FAILED\",\n );\n }\n if (publicKey.length === 0) {\n throw new ECIESError(\"Public key cannot be empty\", \"INVALID_KEY\");\n }\n\n // Normalize public key to uncompressed format\n const pubKey = this.normalizePublicKey(publicKey);\n\n // Generate ephemeral key pair\n let ephemeralPrivateKey: Uint8Array;\n do {\n ephemeralPrivateKey = this.generateRandomBytes(\n CURVE.PRIVATE_KEY_LENGTH,\n );\n } while (!this.verifyPrivateKey(ephemeralPrivateKey));\n\n const ephemeralPublicKey = this.createPublicKey(\n ephemeralPrivateKey,\n false,\n );\n if (!ephemeralPublicKey) {\n throw new ECIESError(\n \"Failed to generate ephemeral public key\",\n \"ENCRYPTION_FAILED\",\n );\n }\n\n // Perform ECDH to get shared secret (raw X coordinate)\n const sharedSecret = this.performECDH(pubKey, ephemeralPrivateKey);\n\n // Derive keys using SHA-512 (eccrypto-compatible KDF)\n const kdf = this.sha512(sharedSecret);\n const encryptionKey = kdf.slice(\n KDF.ENCRYPTION_KEY_OFFSET,\n KDF.ENCRYPTION_KEY_OFFSET + KDF.ENCRYPTION_KEY_LENGTH,\n );\n const macKey = kdf.slice(\n KDF.MAC_KEY_OFFSET,\n KDF.MAC_KEY_OFFSET + KDF.MAC_KEY_LENGTH,\n );\n\n // Generate random IV and encrypt\n const iv = this.generateRandomBytes(CIPHER.IV_LENGTH);\n const ciphertext = await this.aesEncrypt(encryptionKey, iv, message);\n\n // Calculate MAC (Encrypt-then-MAC)\n const macData = concatBytes(iv, ephemeralPublicKey, ciphertext);\n const mac = this.hmacSha256(macKey, macData);\n\n // Clear sensitive data\n this.clearBuffer(ephemeralPrivateKey);\n this.clearBuffer(sharedSecret);\n this.clearBuffer(kdf);\n\n return {\n iv,\n ephemPublicKey: ephemeralPublicKey,\n ciphertext,\n mac,\n };\n } catch (error) {\n if (error instanceof ECIESError) throw error;\n throw new ECIESError(\n `Encryption failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n \"ENCRYPTION_FAILED\",\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n /**\n * Decrypts ECIES encrypted data.\n *\n * @param privateKey - The recipient's private key (32 bytes)\n * @param encrypted - The encrypted data structure from encrypt()\n * @returns Promise resolving to the original plaintext\n */\n async decrypt(\n privateKey: Uint8Array,\n encrypted: ECIESEncrypted,\n ): Promise<Uint8Array> {\n try {\n // Validate inputs\n if (!(privateKey instanceof Uint8Array)) {\n throw new ECIESError(\"Private key must be a Uint8Array\", \"INVALID_KEY\");\n }\n if (!isECIESEncrypted(encrypted)) {\n throw new ECIESError(\n \"Invalid encrypted data structure\",\n \"DECRYPTION_FAILED\",\n );\n }\n if (privateKey.length !== CURVE.PRIVATE_KEY_LENGTH) {\n throw new ECIESError(\n `Invalid private key length: ${privateKey.length}`,\n \"INVALID_KEY\",\n );\n }\n if (!this.verifyPrivateKey(privateKey)) {\n throw new ECIESError(\"Invalid private key\", \"INVALID_KEY\");\n }\n\n // Normalize ephemeral public key to uncompressed format\n const ephemeralPublicKey = this.normalizePublicKey(\n encrypted.ephemPublicKey,\n );\n\n // Perform ECDH to recover shared secret\n const sharedSecret = this.performECDH(ephemeralPublicKey, privateKey);\n\n // Derive keys using SHA-512 (eccrypto-compatible KDF)\n const kdf = this.sha512(sharedSecret);\n const encryptionKey = kdf.slice(\n KDF.ENCRYPTION_KEY_OFFSET,\n KDF.ENCRYPTION_KEY_OFFSET + KDF.ENCRYPTION_KEY_LENGTH,\n );\n const macKey = kdf.slice(\n KDF.MAC_KEY_OFFSET,\n KDF.MAC_KEY_OFFSET + KDF.MAC_KEY_LENGTH,\n );\n\n // Verify MAC before decryption (Encrypt-then-MAC)\n const macData = concatBytes(\n encrypted.iv,\n encrypted.ephemPublicKey,\n encrypted.ciphertext,\n );\n const expectedMac = this.hmacSha256(macKey, macData);\n\n if (!constantTimeEqual(encrypted.mac, expectedMac)) {\n throw new ECIESError(\"MAC verification failed\", \"MAC_MISMATCH\");\n }\n\n // Decrypt the ciphertext\n const decrypted = await this.aesDecrypt(\n encryptionKey,\n encrypted.iv,\n encrypted.ciphertext,\n );\n\n // Clear sensitive data\n this.clearBuffer(sharedSecret);\n this.clearBuffer(kdf);\n\n return decrypted;\n } catch (error) {\n if (error instanceof ECIESError) throw error;\n throw new ECIESError(\n `Decryption failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n \"DECRYPTION_FAILED\",\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n /**\n * Clears sensitive data from memory using multi-pass overwrite.\n *\n * @remarks\n * Uses multiple passes with different patterns to make it harder\n * for JIT compilers to optimize away the operation. While not\n * guaranteed in JavaScript, this is a best-effort approach to\n * clear sensitive data from memory.\n *\n * @param buffer - The buffer to clear\n */\n protected clearBuffer(buffer: Uint8Array): void {\n if (buffer && buffer.length > 0) {\n // Multi-pass overwrite to resist compiler optimization\n buffer.fill(0x00); // Fill with zeros\n buffer.fill(0xff); // Fill with ones\n buffer.fill(0xaa); // Fill with alternating pattern\n buffer.fill(0x00); // Final zero fill\n\n // Additional pattern write to further discourage optimization\n for (let i = 0; i < buffer.length; i++) {\n buffer[i] = (i & 0xff) ^ 0x5a; // XOR with pattern\n }\n buffer.fill(0x00); // Final clear\n }\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/crypto/ecies/base.ts"],"sourcesContent":["import type { ECIESProvider, ECIESEncrypted } from \"./interface\";\nimport { ECIESError, isECIESEncrypted } from \"./interface\";\nimport { CURVE, CIPHER, KDF } from \"./constants\";\nimport { constantTimeEqual } from \"./utils\";\nimport { concat } from \"viem\";\n\n/**\n * Provides shared ECIES encryption logic across platforms using Uint8Array.\n *\n * @remarks\n * Platform implementations extend this class and provide crypto primitives.\n * The base class handles the ECIES protocol flow while maintaining\n * compatibility with the eccrypto data format.\n *\n * **Implementation details:**\n * - KDF: SHA-512(shared_secret) → encKey (32B) || macKey (32B)\n * - Cipher: AES-256-CBC with random 16-byte IV\n * - MAC: HMAC-SHA256(macKey, iv || ephemPublicKey || ciphertext)\n *\n * @category Cryptography\n */\nexport abstract class BaseECIESUint8 implements ECIESProvider {\n // Cache for validated public keys to avoid repeated validation\n private static readonly validatedKeys = new WeakMap<Uint8Array, boolean>();\n\n /**\n * Generates cryptographically secure random bytes.\n *\n * @param length - Number of random bytes to generate.\n * @returns Random bytes array.\n */\n protected abstract generateRandomBytes(length: number): Uint8Array;\n\n /**\n * Verifies a private key is valid for secp256k1.\n *\n * @param privateKey - Private key to verify (32 bytes).\n * @returns `true` if valid private key.\n */\n protected abstract verifyPrivateKey(privateKey: Uint8Array): boolean;\n\n /**\n * Creates a public key from a private key.\n *\n * @param privateKey - Source private key (32 bytes).\n * @param compressed - Generate compressed (33B) or uncompressed (65B) format.\n * @returns Public key or `null` if creation failed.\n */\n protected abstract createPublicKey(\n privateKey: Uint8Array,\n compressed: boolean,\n ): Uint8Array | null;\n\n /**\n * Validates a public key on the secp256k1 curve.\n *\n * @param publicKey - Public key to validate.\n * @returns `true` if valid public key.\n */\n protected abstract validatePublicKey(publicKey: Uint8Array): boolean;\n\n /**\n * Decompresses a compressed public key.\n *\n * @param publicKey - Compressed public key (33 bytes).\n * @returns Uncompressed public key (65 bytes) or `null` if decompression failed.\n */\n protected abstract decompressPublicKey(\n publicKey: Uint8Array,\n ): Uint8Array | null;\n\n /**\n * Performs ECDH key agreement.\n *\n * @param publicKey - Other party's public key.\n * @param privateKey - Your private key.\n * @returns Raw X coordinate of shared point (32 bytes).\n */\n protected abstract performECDH(\n publicKey: Uint8Array,\n privateKey: Uint8Array,\n ): Uint8Array;\n\n /**\n * Computes SHA-512 hash.\n *\n * @param data - Data to hash.\n * @returns SHA-512 hash (64 bytes).\n */\n protected abstract sha512(data: Uint8Array): Uint8Array;\n\n /**\n * Computes HMAC-SHA256 authentication tag.\n *\n * @param key - HMAC key.\n * @param data - Data to authenticate.\n * @returns HMAC-SHA256 (32 bytes).\n */\n protected abstract hmacSha256(key: Uint8Array, data: Uint8Array): Uint8Array;\n\n /**\n * Encrypts data using AES-256-CBC.\n *\n * @param key - Encryption key (32 bytes).\n * @param iv - Initialization vector (16 bytes).\n * @param plaintext - Data to encrypt.\n * @returns Ciphertext with PKCS#7 padding.\n */\n protected abstract aesEncrypt(\n key: Uint8Array,\n iv: Uint8Array,\n plaintext: Uint8Array,\n ): Promise<Uint8Array>;\n\n /**\n * Decrypts data using AES-256-CBC.\n *\n * @param key - Decryption key (32 bytes).\n * @param iv - Initialization vector (16 bytes).\n * @param ciphertext - Data to decrypt.\n * @returns Plaintext with padding removed.\n */\n protected abstract aesDecrypt(\n key: Uint8Array,\n iv: Uint8Array,\n ciphertext: Uint8Array,\n ): Promise<Uint8Array>;\n\n /**\n * Normalizes a public key to uncompressed format.\n *\n * @param publicKey - Public key in any format.\n * @returns Uncompressed public key (65 bytes).\n * @throws {ECIESError} If key format is invalid.\n */\n protected normalizePublicKey(publicKey: Uint8Array): Uint8Array {\n // Check cache first\n if (BaseECIESUint8.validatedKeys.has(publicKey)) {\n return publicKey;\n }\n\n if (publicKey.length === CURVE.UNCOMPRESSED_PUBLIC_KEY_LENGTH) {\n if (publicKey[0] !== CURVE.PREFIX.UNCOMPRESSED) {\n throw new ECIESError(\n \"Invalid uncompressed public key prefix\",\n \"INVALID_KEY\",\n );\n }\n // Validate and cache\n if (!this.validatePublicKey(publicKey)) {\n throw new ECIESError(\"Invalid public key\", \"INVALID_KEY\");\n }\n BaseECIESUint8.validatedKeys.set(publicKey, true);\n return publicKey;\n }\n\n if (publicKey.length === CURVE.COMPRESSED_PUBLIC_KEY_LENGTH) {\n const decompressed = this.decompressPublicKey(publicKey);\n if (!decompressed) {\n throw new ECIESError(\"Failed to decompress public key\", \"INVALID_KEY\");\n }\n // Cache the decompressed key\n BaseECIESUint8.validatedKeys.set(decompressed, true);\n return decompressed;\n }\n\n throw new ECIESError(\n `Invalid public key length: ${publicKey.length}`,\n \"INVALID_KEY\",\n );\n }\n\n /**\n * Normalizes a public key to uncompressed format (65 bytes with 0x04 prefix).\n * Must be implemented by derived classes to handle platform-specific operations.\n *\n * @param publicKey - The public key to normalize\n * @returns The normalized uncompressed public key\n */\n public abstract normalizeToUncompressed(publicKey: Uint8Array): Uint8Array;\n\n /**\n * Encrypts data using ECIES.\n *\n * @param publicKey - The recipient's public key (compressed or uncompressed)\n * @param message - The data to encrypt\n * @returns Promise resolving to encrypted data structure\n */\n async encrypt(\n publicKey: Uint8Array,\n message: Uint8Array,\n ): Promise<ECIESEncrypted> {\n try {\n // Validate inputs\n if (!(publicKey instanceof Uint8Array)) {\n throw new ECIESError(\"Public key must be a Uint8Array\", \"INVALID_KEY\");\n }\n if (!(message instanceof Uint8Array)) {\n throw new ECIESError(\n \"Message must be a Uint8Array\",\n \"ENCRYPTION_FAILED\",\n );\n }\n if (publicKey.length === 0) {\n throw new ECIESError(\"Public key cannot be empty\", \"INVALID_KEY\");\n }\n\n // Normalize public key to uncompressed format\n const pubKey = this.normalizePublicKey(publicKey);\n\n // Generate ephemeral key pair\n let ephemeralPrivateKey: Uint8Array;\n do {\n ephemeralPrivateKey = this.generateRandomBytes(\n CURVE.PRIVATE_KEY_LENGTH,\n );\n } while (!this.verifyPrivateKey(ephemeralPrivateKey));\n\n const ephemeralPublicKey = this.createPublicKey(\n ephemeralPrivateKey,\n false,\n );\n if (!ephemeralPublicKey) {\n throw new ECIESError(\n \"Failed to generate ephemeral public key\",\n \"ENCRYPTION_FAILED\",\n );\n }\n\n // Perform ECDH to get shared secret (raw X coordinate)\n const sharedSecret = this.performECDH(pubKey, ephemeralPrivateKey);\n\n // Derive keys using SHA-512 (eccrypto-compatible KDF)\n const kdf = this.sha512(sharedSecret);\n const encryptionKey = kdf.slice(\n KDF.ENCRYPTION_KEY_OFFSET,\n KDF.ENCRYPTION_KEY_OFFSET + KDF.ENCRYPTION_KEY_LENGTH,\n );\n const macKey = kdf.slice(\n KDF.MAC_KEY_OFFSET,\n KDF.MAC_KEY_OFFSET + KDF.MAC_KEY_LENGTH,\n );\n\n // Generate random IV and encrypt\n const iv = this.generateRandomBytes(CIPHER.IV_LENGTH);\n const ciphertext = await this.aesEncrypt(encryptionKey, iv, message);\n\n // Calculate MAC (Encrypt-then-MAC)\n const macData = concat([iv, ephemeralPublicKey, ciphertext]);\n const mac = this.hmacSha256(macKey, macData);\n\n // Clear sensitive data\n this.clearBuffer(ephemeralPrivateKey);\n this.clearBuffer(sharedSecret);\n this.clearBuffer(kdf);\n\n return {\n iv,\n ephemPublicKey: ephemeralPublicKey,\n ciphertext,\n mac,\n };\n } catch (error) {\n if (error instanceof ECIESError) throw error;\n throw new ECIESError(\n `Encryption failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n \"ENCRYPTION_FAILED\",\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n /**\n * Decrypts ECIES encrypted data.\n *\n * @param privateKey - The recipient's private key (32 bytes)\n * @param encrypted - The encrypted data structure from encrypt()\n * @returns Promise resolving to the original plaintext\n */\n async decrypt(\n privateKey: Uint8Array,\n encrypted: ECIESEncrypted,\n ): Promise<Uint8Array> {\n try {\n // Validate inputs\n if (!(privateKey instanceof Uint8Array)) {\n throw new ECIESError(\"Private key must be a Uint8Array\", \"INVALID_KEY\");\n }\n if (!isECIESEncrypted(encrypted)) {\n throw new ECIESError(\n \"Invalid encrypted data structure\",\n \"DECRYPTION_FAILED\",\n );\n }\n if (privateKey.length !== CURVE.PRIVATE_KEY_LENGTH) {\n throw new ECIESError(\n `Invalid private key length: ${privateKey.length}`,\n \"INVALID_KEY\",\n );\n }\n if (!this.verifyPrivateKey(privateKey)) {\n throw new ECIESError(\"Invalid private key\", \"INVALID_KEY\");\n }\n\n // Normalize ephemeral public key to uncompressed format\n const ephemeralPublicKey = this.normalizePublicKey(\n encrypted.ephemPublicKey,\n );\n\n // Perform ECDH to recover shared secret\n const sharedSecret = this.performECDH(ephemeralPublicKey, privateKey);\n\n // Derive keys using SHA-512 (eccrypto-compatible KDF)\n const kdf = this.sha512(sharedSecret);\n const encryptionKey = kdf.slice(\n KDF.ENCRYPTION_KEY_OFFSET,\n KDF.ENCRYPTION_KEY_OFFSET + KDF.ENCRYPTION_KEY_LENGTH,\n );\n const macKey = kdf.slice(\n KDF.MAC_KEY_OFFSET,\n KDF.MAC_KEY_OFFSET + KDF.MAC_KEY_LENGTH,\n );\n\n // Verify MAC before decryption (Encrypt-then-MAC)\n const macData = concat([\n encrypted.iv,\n encrypted.ephemPublicKey,\n encrypted.ciphertext,\n ]);\n const expectedMac = this.hmacSha256(macKey, macData);\n\n if (!constantTimeEqual(encrypted.mac, expectedMac)) {\n throw new ECIESError(\"MAC verification failed\", \"MAC_MISMATCH\");\n }\n\n // Decrypt the ciphertext\n const decrypted = await this.aesDecrypt(\n encryptionKey,\n encrypted.iv,\n encrypted.ciphertext,\n );\n\n // Clear sensitive data\n this.clearBuffer(sharedSecret);\n this.clearBuffer(kdf);\n\n return decrypted;\n } catch (error) {\n if (error instanceof ECIESError) throw error;\n throw new ECIESError(\n `Decryption failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n \"DECRYPTION_FAILED\",\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n /**\n * Clears sensitive data from memory using multi-pass overwrite.\n *\n * @remarks\n * Uses multiple passes with different patterns to make it harder\n * for JIT compilers to optimize away the operation. While not\n * guaranteed in JavaScript, this is a best-effort approach to\n * clear sensitive data from memory.\n *\n * @param buffer - The buffer to clear\n */\n protected clearBuffer(buffer: Uint8Array): void {\n if (buffer && buffer.length > 0) {\n // Multi-pass overwrite to resist compiler optimization\n buffer.fill(0x00); // Fill with zeros\n buffer.fill(0xff); // Fill with ones\n buffer.fill(0xaa); // Fill with alternating pattern\n buffer.fill(0x00); // Final zero fill\n\n // Additional pattern write to further discourage optimization\n for (let i = 0; i < buffer.length; i++) {\n buffer[i] = (i & 0xff) ^ 0x5a; // XOR with pattern\n }\n buffer.fill(0x00); // Final clear\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,5 +1,4 @@
1
- import { ECIESProvider, ECIESEncrypted } from './interface.js';
2
-
1
+ import type { ECIESProvider, ECIESEncrypted } from "./interface";
3
2
  /**
4
3
  * Provides shared ECIES encryption logic across platforms using Uint8Array.
5
4
  *
@@ -15,7 +14,7 @@ import { ECIESProvider, ECIESEncrypted } from './interface.js';
15
14
  *
16
15
  * @category Cryptography
17
16
  */
18
- declare abstract class BaseECIESUint8 implements ECIESProvider {
17
+ export declare abstract class BaseECIESUint8 implements ECIESProvider {
19
18
  private static readonly validatedKeys;
20
19
  /**
21
20
  * Generates cryptographically secure random bytes.
@@ -139,5 +138,3 @@ declare abstract class BaseECIESUint8 implements ECIESProvider {
139
138
  */
140
139
  protected clearBuffer(buffer: Uint8Array): void;
141
140
  }
142
-
143
- export { BaseECIESUint8 };
@@ -1,10 +1,10 @@
1
- var __defProp = Object.defineProperty;
2
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
1
  import { ECIESError, isECIESEncrypted } from "./interface";
5
2
  import { CURVE, CIPHER, KDF } from "./constants";
6
- import { concatBytes, constantTimeEqual } from "./utils";
7
- const _BaseECIESUint8 = class _BaseECIESUint8 {
3
+ import { constantTimeEqual } from "./utils";
4
+ import { concat } from "viem";
5
+ class BaseECIESUint8 {
6
+ // Cache for validated public keys to avoid repeated validation
7
+ static validatedKeys = /* @__PURE__ */ new WeakMap();
8
8
  /**
9
9
  * Normalizes a public key to uncompressed format.
10
10
  *
@@ -13,7 +13,7 @@ const _BaseECIESUint8 = class _BaseECIESUint8 {
13
13
  * @throws {ECIESError} If key format is invalid.
14
14
  */
15
15
  normalizePublicKey(publicKey) {
16
- if (_BaseECIESUint8.validatedKeys.has(publicKey)) {
16
+ if (BaseECIESUint8.validatedKeys.has(publicKey)) {
17
17
  return publicKey;
18
18
  }
19
19
  if (publicKey.length === CURVE.UNCOMPRESSED_PUBLIC_KEY_LENGTH) {
@@ -26,7 +26,7 @@ const _BaseECIESUint8 = class _BaseECIESUint8 {
26
26
  if (!this.validatePublicKey(publicKey)) {
27
27
  throw new ECIESError("Invalid public key", "INVALID_KEY");
28
28
  }
29
- _BaseECIESUint8.validatedKeys.set(publicKey, true);
29
+ BaseECIESUint8.validatedKeys.set(publicKey, true);
30
30
  return publicKey;
31
31
  }
32
32
  if (publicKey.length === CURVE.COMPRESSED_PUBLIC_KEY_LENGTH) {
@@ -34,7 +34,7 @@ const _BaseECIESUint8 = class _BaseECIESUint8 {
34
34
  if (!decompressed) {
35
35
  throw new ECIESError("Failed to decompress public key", "INVALID_KEY");
36
36
  }
37
- _BaseECIESUint8.validatedKeys.set(decompressed, true);
37
+ BaseECIESUint8.validatedKeys.set(decompressed, true);
38
38
  return decompressed;
39
39
  }
40
40
  throw new ECIESError(
@@ -92,7 +92,7 @@ const _BaseECIESUint8 = class _BaseECIESUint8 {
92
92
  );
93
93
  const iv = this.generateRandomBytes(CIPHER.IV_LENGTH);
94
94
  const ciphertext = await this.aesEncrypt(encryptionKey, iv, message);
95
- const macData = concatBytes(iv, ephemeralPublicKey, ciphertext);
95
+ const macData = concat([iv, ephemeralPublicKey, ciphertext]);
96
96
  const mac = this.hmacSha256(macKey, macData);
97
97
  this.clearBuffer(ephemeralPrivateKey);
98
98
  this.clearBuffer(sharedSecret);
@@ -152,11 +152,11 @@ const _BaseECIESUint8 = class _BaseECIESUint8 {
152
152
  KDF.MAC_KEY_OFFSET,
153
153
  KDF.MAC_KEY_OFFSET + KDF.MAC_KEY_LENGTH
154
154
  );
155
- const macData = concatBytes(
155
+ const macData = concat([
156
156
  encrypted.iv,
157
157
  encrypted.ephemPublicKey,
158
158
  encrypted.ciphertext
159
- );
159
+ ]);
160
160
  const expectedMac = this.hmacSha256(macKey, macData);
161
161
  if (!constantTimeEqual(encrypted.mac, expectedMac)) {
162
162
  throw new ECIESError("MAC verification failed", "MAC_MISMATCH");
@@ -201,10 +201,7 @@ const _BaseECIESUint8 = class _BaseECIESUint8 {
201
201
  buffer.fill(0);
202
202
  }
203
203
  }
204
- };
205
- // Cache for validated public keys to avoid repeated validation
206
- __publicField(_BaseECIESUint8, "validatedKeys", /* @__PURE__ */ new WeakMap());
207
- let BaseECIESUint8 = _BaseECIESUint8;
204
+ }
208
205
  export {
209
206
  BaseECIESUint8
210
207
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/crypto/ecies/base.ts"],"sourcesContent":["import type { ECIESProvider, ECIESEncrypted } from \"./interface\";\nimport { ECIESError, isECIESEncrypted } from \"./interface\";\nimport { CURVE, CIPHER, KDF } from \"./constants\";\nimport { concatBytes, constantTimeEqual } from \"./utils\";\n\n/**\n * Provides shared ECIES encryption logic across platforms using Uint8Array.\n *\n * @remarks\n * Platform implementations extend this class and provide crypto primitives.\n * The base class handles the ECIES protocol flow while maintaining\n * compatibility with the eccrypto data format.\n *\n * **Implementation details:**\n * - KDF: SHA-512(shared_secret) → encKey (32B) || macKey (32B)\n * - Cipher: AES-256-CBC with random 16-byte IV\n * - MAC: HMAC-SHA256(macKey, iv || ephemPublicKey || ciphertext)\n *\n * @category Cryptography\n */\nexport abstract class BaseECIESUint8 implements ECIESProvider {\n // Cache for validated public keys to avoid repeated validation\n private static readonly validatedKeys = new WeakMap<Uint8Array, boolean>();\n\n /**\n * Generates cryptographically secure random bytes.\n *\n * @param length - Number of random bytes to generate.\n * @returns Random bytes array.\n */\n protected abstract generateRandomBytes(length: number): Uint8Array;\n\n /**\n * Verifies a private key is valid for secp256k1.\n *\n * @param privateKey - Private key to verify (32 bytes).\n * @returns `true` if valid private key.\n */\n protected abstract verifyPrivateKey(privateKey: Uint8Array): boolean;\n\n /**\n * Creates a public key from a private key.\n *\n * @param privateKey - Source private key (32 bytes).\n * @param compressed - Generate compressed (33B) or uncompressed (65B) format.\n * @returns Public key or `null` if creation failed.\n */\n protected abstract createPublicKey(\n privateKey: Uint8Array,\n compressed: boolean,\n ): Uint8Array | null;\n\n /**\n * Validates a public key on the secp256k1 curve.\n *\n * @param publicKey - Public key to validate.\n * @returns `true` if valid public key.\n */\n protected abstract validatePublicKey(publicKey: Uint8Array): boolean;\n\n /**\n * Decompresses a compressed public key.\n *\n * @param publicKey - Compressed public key (33 bytes).\n * @returns Uncompressed public key (65 bytes) or `null` if decompression failed.\n */\n protected abstract decompressPublicKey(\n publicKey: Uint8Array,\n ): Uint8Array | null;\n\n /**\n * Performs ECDH key agreement.\n *\n * @param publicKey - Other party's public key.\n * @param privateKey - Your private key.\n * @returns Raw X coordinate of shared point (32 bytes).\n */\n protected abstract performECDH(\n publicKey: Uint8Array,\n privateKey: Uint8Array,\n ): Uint8Array;\n\n /**\n * Computes SHA-512 hash.\n *\n * @param data - Data to hash.\n * @returns SHA-512 hash (64 bytes).\n */\n protected abstract sha512(data: Uint8Array): Uint8Array;\n\n /**\n * Computes HMAC-SHA256 authentication tag.\n *\n * @param key - HMAC key.\n * @param data - Data to authenticate.\n * @returns HMAC-SHA256 (32 bytes).\n */\n protected abstract hmacSha256(key: Uint8Array, data: Uint8Array): Uint8Array;\n\n /**\n * Encrypts data using AES-256-CBC.\n *\n * @param key - Encryption key (32 bytes).\n * @param iv - Initialization vector (16 bytes).\n * @param plaintext - Data to encrypt.\n * @returns Ciphertext with PKCS#7 padding.\n */\n protected abstract aesEncrypt(\n key: Uint8Array,\n iv: Uint8Array,\n plaintext: Uint8Array,\n ): Promise<Uint8Array>;\n\n /**\n * Decrypts data using AES-256-CBC.\n *\n * @param key - Decryption key (32 bytes).\n * @param iv - Initialization vector (16 bytes).\n * @param ciphertext - Data to decrypt.\n * @returns Plaintext with padding removed.\n */\n protected abstract aesDecrypt(\n key: Uint8Array,\n iv: Uint8Array,\n ciphertext: Uint8Array,\n ): Promise<Uint8Array>;\n\n /**\n * Normalizes a public key to uncompressed format.\n *\n * @param publicKey - Public key in any format.\n * @returns Uncompressed public key (65 bytes).\n * @throws {ECIESError} If key format is invalid.\n */\n protected normalizePublicKey(publicKey: Uint8Array): Uint8Array {\n // Check cache first\n if (BaseECIESUint8.validatedKeys.has(publicKey)) {\n return publicKey;\n }\n\n if (publicKey.length === CURVE.UNCOMPRESSED_PUBLIC_KEY_LENGTH) {\n if (publicKey[0] !== CURVE.PREFIX.UNCOMPRESSED) {\n throw new ECIESError(\n \"Invalid uncompressed public key prefix\",\n \"INVALID_KEY\",\n );\n }\n // Validate and cache\n if (!this.validatePublicKey(publicKey)) {\n throw new ECIESError(\"Invalid public key\", \"INVALID_KEY\");\n }\n BaseECIESUint8.validatedKeys.set(publicKey, true);\n return publicKey;\n }\n\n if (publicKey.length === CURVE.COMPRESSED_PUBLIC_KEY_LENGTH) {\n const decompressed = this.decompressPublicKey(publicKey);\n if (!decompressed) {\n throw new ECIESError(\"Failed to decompress public key\", \"INVALID_KEY\");\n }\n // Cache the decompressed key\n BaseECIESUint8.validatedKeys.set(decompressed, true);\n return decompressed;\n }\n\n throw new ECIESError(\n `Invalid public key length: ${publicKey.length}`,\n \"INVALID_KEY\",\n );\n }\n\n /**\n * Normalizes a public key to uncompressed format (65 bytes with 0x04 prefix).\n * Must be implemented by derived classes to handle platform-specific operations.\n *\n * @param publicKey - The public key to normalize\n * @returns The normalized uncompressed public key\n */\n public abstract normalizeToUncompressed(publicKey: Uint8Array): Uint8Array;\n\n /**\n * Encrypts data using ECIES.\n *\n * @param publicKey - The recipient's public key (compressed or uncompressed)\n * @param message - The data to encrypt\n * @returns Promise resolving to encrypted data structure\n */\n async encrypt(\n publicKey: Uint8Array,\n message: Uint8Array,\n ): Promise<ECIESEncrypted> {\n try {\n // Validate inputs\n if (!(publicKey instanceof Uint8Array)) {\n throw new ECIESError(\"Public key must be a Uint8Array\", \"INVALID_KEY\");\n }\n if (!(message instanceof Uint8Array)) {\n throw new ECIESError(\n \"Message must be a Uint8Array\",\n \"ENCRYPTION_FAILED\",\n );\n }\n if (publicKey.length === 0) {\n throw new ECIESError(\"Public key cannot be empty\", \"INVALID_KEY\");\n }\n\n // Normalize public key to uncompressed format\n const pubKey = this.normalizePublicKey(publicKey);\n\n // Generate ephemeral key pair\n let ephemeralPrivateKey: Uint8Array;\n do {\n ephemeralPrivateKey = this.generateRandomBytes(\n CURVE.PRIVATE_KEY_LENGTH,\n );\n } while (!this.verifyPrivateKey(ephemeralPrivateKey));\n\n const ephemeralPublicKey = this.createPublicKey(\n ephemeralPrivateKey,\n false,\n );\n if (!ephemeralPublicKey) {\n throw new ECIESError(\n \"Failed to generate ephemeral public key\",\n \"ENCRYPTION_FAILED\",\n );\n }\n\n // Perform ECDH to get shared secret (raw X coordinate)\n const sharedSecret = this.performECDH(pubKey, ephemeralPrivateKey);\n\n // Derive keys using SHA-512 (eccrypto-compatible KDF)\n const kdf = this.sha512(sharedSecret);\n const encryptionKey = kdf.slice(\n KDF.ENCRYPTION_KEY_OFFSET,\n KDF.ENCRYPTION_KEY_OFFSET + KDF.ENCRYPTION_KEY_LENGTH,\n );\n const macKey = kdf.slice(\n KDF.MAC_KEY_OFFSET,\n KDF.MAC_KEY_OFFSET + KDF.MAC_KEY_LENGTH,\n );\n\n // Generate random IV and encrypt\n const iv = this.generateRandomBytes(CIPHER.IV_LENGTH);\n const ciphertext = await this.aesEncrypt(encryptionKey, iv, message);\n\n // Calculate MAC (Encrypt-then-MAC)\n const macData = concatBytes(iv, ephemeralPublicKey, ciphertext);\n const mac = this.hmacSha256(macKey, macData);\n\n // Clear sensitive data\n this.clearBuffer(ephemeralPrivateKey);\n this.clearBuffer(sharedSecret);\n this.clearBuffer(kdf);\n\n return {\n iv,\n ephemPublicKey: ephemeralPublicKey,\n ciphertext,\n mac,\n };\n } catch (error) {\n if (error instanceof ECIESError) throw error;\n throw new ECIESError(\n `Encryption failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n \"ENCRYPTION_FAILED\",\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n /**\n * Decrypts ECIES encrypted data.\n *\n * @param privateKey - The recipient's private key (32 bytes)\n * @param encrypted - The encrypted data structure from encrypt()\n * @returns Promise resolving to the original plaintext\n */\n async decrypt(\n privateKey: Uint8Array,\n encrypted: ECIESEncrypted,\n ): Promise<Uint8Array> {\n try {\n // Validate inputs\n if (!(privateKey instanceof Uint8Array)) {\n throw new ECIESError(\"Private key must be a Uint8Array\", \"INVALID_KEY\");\n }\n if (!isECIESEncrypted(encrypted)) {\n throw new ECIESError(\n \"Invalid encrypted data structure\",\n \"DECRYPTION_FAILED\",\n );\n }\n if (privateKey.length !== CURVE.PRIVATE_KEY_LENGTH) {\n throw new ECIESError(\n `Invalid private key length: ${privateKey.length}`,\n \"INVALID_KEY\",\n );\n }\n if (!this.verifyPrivateKey(privateKey)) {\n throw new ECIESError(\"Invalid private key\", \"INVALID_KEY\");\n }\n\n // Normalize ephemeral public key to uncompressed format\n const ephemeralPublicKey = this.normalizePublicKey(\n encrypted.ephemPublicKey,\n );\n\n // Perform ECDH to recover shared secret\n const sharedSecret = this.performECDH(ephemeralPublicKey, privateKey);\n\n // Derive keys using SHA-512 (eccrypto-compatible KDF)\n const kdf = this.sha512(sharedSecret);\n const encryptionKey = kdf.slice(\n KDF.ENCRYPTION_KEY_OFFSET,\n KDF.ENCRYPTION_KEY_OFFSET + KDF.ENCRYPTION_KEY_LENGTH,\n );\n const macKey = kdf.slice(\n KDF.MAC_KEY_OFFSET,\n KDF.MAC_KEY_OFFSET + KDF.MAC_KEY_LENGTH,\n );\n\n // Verify MAC before decryption (Encrypt-then-MAC)\n const macData = concatBytes(\n encrypted.iv,\n encrypted.ephemPublicKey,\n encrypted.ciphertext,\n );\n const expectedMac = this.hmacSha256(macKey, macData);\n\n if (!constantTimeEqual(encrypted.mac, expectedMac)) {\n throw new ECIESError(\"MAC verification failed\", \"MAC_MISMATCH\");\n }\n\n // Decrypt the ciphertext\n const decrypted = await this.aesDecrypt(\n encryptionKey,\n encrypted.iv,\n encrypted.ciphertext,\n );\n\n // Clear sensitive data\n this.clearBuffer(sharedSecret);\n this.clearBuffer(kdf);\n\n return decrypted;\n } catch (error) {\n if (error instanceof ECIESError) throw error;\n throw new ECIESError(\n `Decryption failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n \"DECRYPTION_FAILED\",\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n /**\n * Clears sensitive data from memory using multi-pass overwrite.\n *\n * @remarks\n * Uses multiple passes with different patterns to make it harder\n * for JIT compilers to optimize away the operation. While not\n * guaranteed in JavaScript, this is a best-effort approach to\n * clear sensitive data from memory.\n *\n * @param buffer - The buffer to clear\n */\n protected clearBuffer(buffer: Uint8Array): void {\n if (buffer && buffer.length > 0) {\n // Multi-pass overwrite to resist compiler optimization\n buffer.fill(0x00); // Fill with zeros\n buffer.fill(0xff); // Fill with ones\n buffer.fill(0xaa); // Fill with alternating pattern\n buffer.fill(0x00); // Final zero fill\n\n // Additional pattern write to further discourage optimization\n for (let i = 0; i < buffer.length; i++) {\n buffer[i] = (i & 0xff) ^ 0x5a; // XOR with pattern\n }\n buffer.fill(0x00); // Final clear\n }\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/crypto/ecies/base.ts"],"sourcesContent":["import type { ECIESProvider, ECIESEncrypted } from \"./interface\";\nimport { ECIESError, isECIESEncrypted } from \"./interface\";\nimport { CURVE, CIPHER, KDF } from \"./constants\";\nimport { constantTimeEqual } from \"./utils\";\nimport { concat } from \"viem\";\n\n/**\n * Provides shared ECIES encryption logic across platforms using Uint8Array.\n *\n * @remarks\n * Platform implementations extend this class and provide crypto primitives.\n * The base class handles the ECIES protocol flow while maintaining\n * compatibility with the eccrypto data format.\n *\n * **Implementation details:**\n * - KDF: SHA-512(shared_secret) → encKey (32B) || macKey (32B)\n * - Cipher: AES-256-CBC with random 16-byte IV\n * - MAC: HMAC-SHA256(macKey, iv || ephemPublicKey || ciphertext)\n *\n * @category Cryptography\n */\nexport abstract class BaseECIESUint8 implements ECIESProvider {\n // Cache for validated public keys to avoid repeated validation\n private static readonly validatedKeys = new WeakMap<Uint8Array, boolean>();\n\n /**\n * Generates cryptographically secure random bytes.\n *\n * @param length - Number of random bytes to generate.\n * @returns Random bytes array.\n */\n protected abstract generateRandomBytes(length: number): Uint8Array;\n\n /**\n * Verifies a private key is valid for secp256k1.\n *\n * @param privateKey - Private key to verify (32 bytes).\n * @returns `true` if valid private key.\n */\n protected abstract verifyPrivateKey(privateKey: Uint8Array): boolean;\n\n /**\n * Creates a public key from a private key.\n *\n * @param privateKey - Source private key (32 bytes).\n * @param compressed - Generate compressed (33B) or uncompressed (65B) format.\n * @returns Public key or `null` if creation failed.\n */\n protected abstract createPublicKey(\n privateKey: Uint8Array,\n compressed: boolean,\n ): Uint8Array | null;\n\n /**\n * Validates a public key on the secp256k1 curve.\n *\n * @param publicKey - Public key to validate.\n * @returns `true` if valid public key.\n */\n protected abstract validatePublicKey(publicKey: Uint8Array): boolean;\n\n /**\n * Decompresses a compressed public key.\n *\n * @param publicKey - Compressed public key (33 bytes).\n * @returns Uncompressed public key (65 bytes) or `null` if decompression failed.\n */\n protected abstract decompressPublicKey(\n publicKey: Uint8Array,\n ): Uint8Array | null;\n\n /**\n * Performs ECDH key agreement.\n *\n * @param publicKey - Other party's public key.\n * @param privateKey - Your private key.\n * @returns Raw X coordinate of shared point (32 bytes).\n */\n protected abstract performECDH(\n publicKey: Uint8Array,\n privateKey: Uint8Array,\n ): Uint8Array;\n\n /**\n * Computes SHA-512 hash.\n *\n * @param data - Data to hash.\n * @returns SHA-512 hash (64 bytes).\n */\n protected abstract sha512(data: Uint8Array): Uint8Array;\n\n /**\n * Computes HMAC-SHA256 authentication tag.\n *\n * @param key - HMAC key.\n * @param data - Data to authenticate.\n * @returns HMAC-SHA256 (32 bytes).\n */\n protected abstract hmacSha256(key: Uint8Array, data: Uint8Array): Uint8Array;\n\n /**\n * Encrypts data using AES-256-CBC.\n *\n * @param key - Encryption key (32 bytes).\n * @param iv - Initialization vector (16 bytes).\n * @param plaintext - Data to encrypt.\n * @returns Ciphertext with PKCS#7 padding.\n */\n protected abstract aesEncrypt(\n key: Uint8Array,\n iv: Uint8Array,\n plaintext: Uint8Array,\n ): Promise<Uint8Array>;\n\n /**\n * Decrypts data using AES-256-CBC.\n *\n * @param key - Decryption key (32 bytes).\n * @param iv - Initialization vector (16 bytes).\n * @param ciphertext - Data to decrypt.\n * @returns Plaintext with padding removed.\n */\n protected abstract aesDecrypt(\n key: Uint8Array,\n iv: Uint8Array,\n ciphertext: Uint8Array,\n ): Promise<Uint8Array>;\n\n /**\n * Normalizes a public key to uncompressed format.\n *\n * @param publicKey - Public key in any format.\n * @returns Uncompressed public key (65 bytes).\n * @throws {ECIESError} If key format is invalid.\n */\n protected normalizePublicKey(publicKey: Uint8Array): Uint8Array {\n // Check cache first\n if (BaseECIESUint8.validatedKeys.has(publicKey)) {\n return publicKey;\n }\n\n if (publicKey.length === CURVE.UNCOMPRESSED_PUBLIC_KEY_LENGTH) {\n if (publicKey[0] !== CURVE.PREFIX.UNCOMPRESSED) {\n throw new ECIESError(\n \"Invalid uncompressed public key prefix\",\n \"INVALID_KEY\",\n );\n }\n // Validate and cache\n if (!this.validatePublicKey(publicKey)) {\n throw new ECIESError(\"Invalid public key\", \"INVALID_KEY\");\n }\n BaseECIESUint8.validatedKeys.set(publicKey, true);\n return publicKey;\n }\n\n if (publicKey.length === CURVE.COMPRESSED_PUBLIC_KEY_LENGTH) {\n const decompressed = this.decompressPublicKey(publicKey);\n if (!decompressed) {\n throw new ECIESError(\"Failed to decompress public key\", \"INVALID_KEY\");\n }\n // Cache the decompressed key\n BaseECIESUint8.validatedKeys.set(decompressed, true);\n return decompressed;\n }\n\n throw new ECIESError(\n `Invalid public key length: ${publicKey.length}`,\n \"INVALID_KEY\",\n );\n }\n\n /**\n * Normalizes a public key to uncompressed format (65 bytes with 0x04 prefix).\n * Must be implemented by derived classes to handle platform-specific operations.\n *\n * @param publicKey - The public key to normalize\n * @returns The normalized uncompressed public key\n */\n public abstract normalizeToUncompressed(publicKey: Uint8Array): Uint8Array;\n\n /**\n * Encrypts data using ECIES.\n *\n * @param publicKey - The recipient's public key (compressed or uncompressed)\n * @param message - The data to encrypt\n * @returns Promise resolving to encrypted data structure\n */\n async encrypt(\n publicKey: Uint8Array,\n message: Uint8Array,\n ): Promise<ECIESEncrypted> {\n try {\n // Validate inputs\n if (!(publicKey instanceof Uint8Array)) {\n throw new ECIESError(\"Public key must be a Uint8Array\", \"INVALID_KEY\");\n }\n if (!(message instanceof Uint8Array)) {\n throw new ECIESError(\n \"Message must be a Uint8Array\",\n \"ENCRYPTION_FAILED\",\n );\n }\n if (publicKey.length === 0) {\n throw new ECIESError(\"Public key cannot be empty\", \"INVALID_KEY\");\n }\n\n // Normalize public key to uncompressed format\n const pubKey = this.normalizePublicKey(publicKey);\n\n // Generate ephemeral key pair\n let ephemeralPrivateKey: Uint8Array;\n do {\n ephemeralPrivateKey = this.generateRandomBytes(\n CURVE.PRIVATE_KEY_LENGTH,\n );\n } while (!this.verifyPrivateKey(ephemeralPrivateKey));\n\n const ephemeralPublicKey = this.createPublicKey(\n ephemeralPrivateKey,\n false,\n );\n if (!ephemeralPublicKey) {\n throw new ECIESError(\n \"Failed to generate ephemeral public key\",\n \"ENCRYPTION_FAILED\",\n );\n }\n\n // Perform ECDH to get shared secret (raw X coordinate)\n const sharedSecret = this.performECDH(pubKey, ephemeralPrivateKey);\n\n // Derive keys using SHA-512 (eccrypto-compatible KDF)\n const kdf = this.sha512(sharedSecret);\n const encryptionKey = kdf.slice(\n KDF.ENCRYPTION_KEY_OFFSET,\n KDF.ENCRYPTION_KEY_OFFSET + KDF.ENCRYPTION_KEY_LENGTH,\n );\n const macKey = kdf.slice(\n KDF.MAC_KEY_OFFSET,\n KDF.MAC_KEY_OFFSET + KDF.MAC_KEY_LENGTH,\n );\n\n // Generate random IV and encrypt\n const iv = this.generateRandomBytes(CIPHER.IV_LENGTH);\n const ciphertext = await this.aesEncrypt(encryptionKey, iv, message);\n\n // Calculate MAC (Encrypt-then-MAC)\n const macData = concat([iv, ephemeralPublicKey, ciphertext]);\n const mac = this.hmacSha256(macKey, macData);\n\n // Clear sensitive data\n this.clearBuffer(ephemeralPrivateKey);\n this.clearBuffer(sharedSecret);\n this.clearBuffer(kdf);\n\n return {\n iv,\n ephemPublicKey: ephemeralPublicKey,\n ciphertext,\n mac,\n };\n } catch (error) {\n if (error instanceof ECIESError) throw error;\n throw new ECIESError(\n `Encryption failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n \"ENCRYPTION_FAILED\",\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n /**\n * Decrypts ECIES encrypted data.\n *\n * @param privateKey - The recipient's private key (32 bytes)\n * @param encrypted - The encrypted data structure from encrypt()\n * @returns Promise resolving to the original plaintext\n */\n async decrypt(\n privateKey: Uint8Array,\n encrypted: ECIESEncrypted,\n ): Promise<Uint8Array> {\n try {\n // Validate inputs\n if (!(privateKey instanceof Uint8Array)) {\n throw new ECIESError(\"Private key must be a Uint8Array\", \"INVALID_KEY\");\n }\n if (!isECIESEncrypted(encrypted)) {\n throw new ECIESError(\n \"Invalid encrypted data structure\",\n \"DECRYPTION_FAILED\",\n );\n }\n if (privateKey.length !== CURVE.PRIVATE_KEY_LENGTH) {\n throw new ECIESError(\n `Invalid private key length: ${privateKey.length}`,\n \"INVALID_KEY\",\n );\n }\n if (!this.verifyPrivateKey(privateKey)) {\n throw new ECIESError(\"Invalid private key\", \"INVALID_KEY\");\n }\n\n // Normalize ephemeral public key to uncompressed format\n const ephemeralPublicKey = this.normalizePublicKey(\n encrypted.ephemPublicKey,\n );\n\n // Perform ECDH to recover shared secret\n const sharedSecret = this.performECDH(ephemeralPublicKey, privateKey);\n\n // Derive keys using SHA-512 (eccrypto-compatible KDF)\n const kdf = this.sha512(sharedSecret);\n const encryptionKey = kdf.slice(\n KDF.ENCRYPTION_KEY_OFFSET,\n KDF.ENCRYPTION_KEY_OFFSET + KDF.ENCRYPTION_KEY_LENGTH,\n );\n const macKey = kdf.slice(\n KDF.MAC_KEY_OFFSET,\n KDF.MAC_KEY_OFFSET + KDF.MAC_KEY_LENGTH,\n );\n\n // Verify MAC before decryption (Encrypt-then-MAC)\n const macData = concat([\n encrypted.iv,\n encrypted.ephemPublicKey,\n encrypted.ciphertext,\n ]);\n const expectedMac = this.hmacSha256(macKey, macData);\n\n if (!constantTimeEqual(encrypted.mac, expectedMac)) {\n throw new ECIESError(\"MAC verification failed\", \"MAC_MISMATCH\");\n }\n\n // Decrypt the ciphertext\n const decrypted = await this.aesDecrypt(\n encryptionKey,\n encrypted.iv,\n encrypted.ciphertext,\n );\n\n // Clear sensitive data\n this.clearBuffer(sharedSecret);\n this.clearBuffer(kdf);\n\n return decrypted;\n } catch (error) {\n if (error instanceof ECIESError) throw error;\n throw new ECIESError(\n `Decryption failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n \"DECRYPTION_FAILED\",\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n /**\n * Clears sensitive data from memory using multi-pass overwrite.\n *\n * @remarks\n * Uses multiple passes with different patterns to make it harder\n * for JIT compilers to optimize away the operation. While not\n * guaranteed in JavaScript, this is a best-effort approach to\n * clear sensitive data from memory.\n *\n * @param buffer - The buffer to clear\n */\n protected clearBuffer(buffer: Uint8Array): void {\n if (buffer && buffer.length > 0) {\n // Multi-pass overwrite to resist compiler optimization\n buffer.fill(0x00); // Fill with zeros\n buffer.fill(0xff); // Fill with ones\n buffer.fill(0xaa); // Fill with alternating pattern\n buffer.fill(0x00); // Final zero fill\n\n // Additional pattern write to further discourage optimization\n for (let i = 0; i < buffer.length; i++) {\n buffer[i] = (i & 0xff) ^ 0x5a; // XOR with pattern\n }\n buffer.fill(0x00); // Final clear\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -33,6 +33,7 @@ __export(browser_exports, {
33
33
  module.exports = __toCommonJS(browser_exports);
34
34
  var secp256k1 = __toESM(require("@noble/secp256k1"), 1);
35
35
  var import_base = require("./base");
36
+ var import_viem = require("viem");
36
37
  var import_hmac = require("@noble/hashes/hmac");
37
38
  var import_sha2 = require("@noble/hashes/sha2");
38
39
  class BrowserECIESUint8Provider extends import_base.BaseECIESUint8 {
@@ -142,7 +143,7 @@ class BrowserECIESUint8Provider extends import_base.BaseECIESUint8 {
142
143
  const decompressed = this.decompressPublicKey(publicKey);
143
144
  if (!decompressed) {
144
145
  throw new Error(
145
- `Failed to decompress public key with prefix 0x${publicKey[0].toString(16).padStart(2, "0")}`
146
+ `Failed to decompress public key with prefix ${(0, import_viem.toHex)(publicKey[0])}`
146
147
  );
147
148
  }
148
149
  return decompressed;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/crypto/ecies/browser.ts"],"sourcesContent":["/**\n * Browser implementation of ECIES using @noble/secp256k1 with Uint8Array\n *\n * @remarks\n * Uses native browser crypto APIs and @noble/secp256k1 for elliptic curve operations.\n * This implementation is polyfill-free and works in all modern browsers.\n */\n\nimport * as secp256k1 from \"@noble/secp256k1\";\nimport { BaseECIESUint8 } from \"./base\";\nimport { hmac } from \"@noble/hashes/hmac\";\nimport { sha256, sha512 as nobleSha512 } from \"@noble/hashes/sha2\";\n\n/**\n * Browser-specific ECIES provider using @noble/secp256k1\n *\n * @remarks\n * This implementation uses:\n * - Web Crypto API for AES operations\n * - @noble/secp256k1 for elliptic curve operations\n * - @noble/hashes for SHA and HMAC operations\n * - No Buffer or Node.js dependencies\n */\nexport class BrowserECIESUint8Provider extends BaseECIESUint8 {\n protected generateRandomBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n crypto.getRandomValues(bytes);\n return bytes;\n }\n\n protected verifyPrivateKey(privateKey: Uint8Array): boolean {\n try {\n return secp256k1.utils.isValidPrivateKey(privateKey);\n } catch {\n return false;\n }\n }\n\n protected createPublicKey(\n privateKey: Uint8Array,\n compressed: boolean,\n ): Uint8Array | null {\n try {\n return secp256k1.getPublicKey(privateKey, compressed);\n } catch {\n return null;\n }\n }\n\n protected validatePublicKey(publicKey: Uint8Array): boolean {\n try {\n // @noble/secp256k1 will throw if the point is not on the curve\n secp256k1.Point.fromHex(publicKey);\n return true;\n } catch {\n return false;\n }\n }\n\n protected decompressPublicKey(publicKey: Uint8Array): Uint8Array | null {\n try {\n // @noble/secp256k1 handles both compressed and uncompressed\n const point = secp256k1.Point.fromHex(publicKey);\n return point.toRawBytes(false); // false = uncompressed\n } catch {\n return null;\n }\n }\n\n protected performECDH(\n publicKey: Uint8Array,\n privateKey: Uint8Array,\n ): Uint8Array {\n try {\n // Use @noble/secp256k1's getSharedSecret which is optimized and secure\n // The 'true' parameter returns the raw x-coordinate (32 bytes)\n // This matches eccrypto's behavior\n const sharedPoint = secp256k1.getSharedSecret(\n privateKey,\n publicKey,\n true,\n );\n\n // getSharedSecret returns compressed point (33 bytes) when true\n // We need just the x-coordinate (32 bytes) for eccrypto compatibility\n // Remove the prefix byte\n return sharedPoint.slice(1);\n } catch (error) {\n throw new Error(\n `ECDH failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n protected sha512(data: Uint8Array): Uint8Array {\n return nobleSha512(data);\n }\n\n protected hmacSha256(key: Uint8Array, data: Uint8Array): Uint8Array {\n return hmac(sha256, key, data);\n }\n\n protected async aesEncrypt(\n key: Uint8Array,\n iv: Uint8Array,\n plaintext: Uint8Array,\n ): Promise<Uint8Array> {\n // Import the key for AES-CBC\n const cryptoKey = await crypto.subtle.importKey(\n \"raw\",\n key as BufferSource,\n { name: \"AES-CBC\" },\n false,\n [\"encrypt\"],\n );\n\n // Encrypt with Web Crypto API\n // Note: Web Crypto API automatically handles PKCS#7 padding for AES-CBC\n const encrypted = await crypto.subtle.encrypt(\n { name: \"AES-CBC\", iv: iv as BufferSource },\n cryptoKey,\n plaintext as BufferSource,\n );\n\n return new Uint8Array(encrypted);\n }\n\n protected async aesDecrypt(\n key: Uint8Array,\n iv: Uint8Array,\n ciphertext: Uint8Array,\n ): Promise<Uint8Array> {\n // Import the key for AES-CBC\n const cryptoKey = await crypto.subtle.importKey(\n \"raw\",\n key as BufferSource,\n { name: \"AES-CBC\" },\n false,\n [\"decrypt\"],\n );\n\n // Decrypt with Web Crypto API\n // Note: Web Crypto API automatically handles PKCS#7 padding removal\n const decrypted = await crypto.subtle.decrypt(\n { name: \"AES-CBC\", iv: iv as BufferSource },\n cryptoKey,\n ciphertext as BufferSource,\n );\n\n return new Uint8Array(decrypted);\n }\n\n /**\n * Normalizes a public key to uncompressed format (65 bytes with 0x04 prefix).\n * Handles compressed (33 bytes) and uncompressed (65 bytes) formats only.\n *\n * @remarks\n * Strict policy: Does not accept 64-byte raw coordinates to avoid masking\n * malformed data. Callers must provide properly formatted keys.\n *\n * @param publicKey - The public key to normalize (33 or 65 bytes)\n * @returns The normalized uncompressed public key (65 bytes)\n * @throws {Error} When public key format is invalid or decompression fails\n */\n normalizeToUncompressed(publicKey: Uint8Array): Uint8Array {\n const len = publicKey.length;\n\n // Already uncompressed\n if (len === 65 && publicKey[0] === 0x04) {\n return publicKey;\n }\n\n // Compressed - decompress using @noble/secp256k1\n if (len === 33 && (publicKey[0] === 0x02 || publicKey[0] === 0x03)) {\n const decompressed = this.decompressPublicKey(publicKey);\n if (!decompressed) {\n throw new Error(\n `Failed to decompress public key with prefix 0x${publicKey[0].toString(16).padStart(2, \"0\")}`,\n );\n }\n return decompressed;\n }\n\n // Reject raw coordinates (64 bytes) - require proper formatting\n if (len === 64) {\n throw new Error(\n \"Raw public key coordinates (64 bytes) are not accepted. \" +\n \"Please provide a properly formatted compressed (33 bytes) or uncompressed (65 bytes) public key.\",\n );\n }\n\n throw new Error(\n `Invalid public key format: expected compressed (33 bytes) or uncompressed (65 bytes), got ${len} bytes`,\n );\n }\n}\n"],"mappings":"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","names":["nobleSha512"]}
1
+ {"version":3,"sources":["../../../src/crypto/ecies/browser.ts"],"sourcesContent":["/**\n * Browser implementation of ECIES using @noble/secp256k1 with Uint8Array\n *\n * @remarks\n * Uses native browser crypto APIs and @noble/secp256k1 for elliptic curve operations.\n * This implementation is polyfill-free and works in all modern browsers.\n */\n\nimport * as secp256k1 from \"@noble/secp256k1\";\nimport { BaseECIESUint8 } from \"./base\";\nimport { toHex } from \"viem\";\nimport { hmac } from \"@noble/hashes/hmac\";\nimport { sha256, sha512 as nobleSha512 } from \"@noble/hashes/sha2\";\n\n/**\n * Browser-specific ECIES provider using @noble/secp256k1\n *\n * @remarks\n * This implementation uses:\n * - Web Crypto API for AES operations\n * - @noble/secp256k1 for elliptic curve operations\n * - @noble/hashes for SHA and HMAC operations\n * - No Buffer or Node.js dependencies\n */\nexport class BrowserECIESUint8Provider extends BaseECIESUint8 {\n protected generateRandomBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n crypto.getRandomValues(bytes);\n return bytes;\n }\n\n protected verifyPrivateKey(privateKey: Uint8Array): boolean {\n try {\n return secp256k1.utils.isValidPrivateKey(privateKey);\n } catch {\n return false;\n }\n }\n\n protected createPublicKey(\n privateKey: Uint8Array,\n compressed: boolean,\n ): Uint8Array | null {\n try {\n return secp256k1.getPublicKey(privateKey, compressed);\n } catch {\n return null;\n }\n }\n\n protected validatePublicKey(publicKey: Uint8Array): boolean {\n try {\n // @noble/secp256k1 will throw if the point is not on the curve\n secp256k1.Point.fromHex(publicKey);\n return true;\n } catch {\n return false;\n }\n }\n\n protected decompressPublicKey(publicKey: Uint8Array): Uint8Array | null {\n try {\n // @noble/secp256k1 handles both compressed and uncompressed\n const point = secp256k1.Point.fromHex(publicKey);\n return point.toRawBytes(false); // false = uncompressed\n } catch {\n return null;\n }\n }\n\n protected performECDH(\n publicKey: Uint8Array,\n privateKey: Uint8Array,\n ): Uint8Array {\n try {\n // Use @noble/secp256k1's getSharedSecret which is optimized and secure\n // The 'true' parameter returns the raw x-coordinate (32 bytes)\n // This matches eccrypto's behavior\n const sharedPoint = secp256k1.getSharedSecret(\n privateKey,\n publicKey,\n true,\n );\n\n // getSharedSecret returns compressed point (33 bytes) when true\n // We need just the x-coordinate (32 bytes) for eccrypto compatibility\n // Remove the prefix byte\n return sharedPoint.slice(1);\n } catch (error) {\n throw new Error(\n `ECDH failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n protected sha512(data: Uint8Array): Uint8Array {\n return nobleSha512(data);\n }\n\n protected hmacSha256(key: Uint8Array, data: Uint8Array): Uint8Array {\n return hmac(sha256, key, data);\n }\n\n protected async aesEncrypt(\n key: Uint8Array,\n iv: Uint8Array,\n plaintext: Uint8Array,\n ): Promise<Uint8Array> {\n // Import the key for AES-CBC\n const cryptoKey = await crypto.subtle.importKey(\n \"raw\",\n key as BufferSource,\n { name: \"AES-CBC\" },\n false,\n [\"encrypt\"],\n );\n\n // Encrypt with Web Crypto API\n // Note: Web Crypto API automatically handles PKCS#7 padding for AES-CBC\n const encrypted = await crypto.subtle.encrypt(\n { name: \"AES-CBC\", iv: iv as BufferSource },\n cryptoKey,\n plaintext as BufferSource,\n );\n\n return new Uint8Array(encrypted);\n }\n\n protected async aesDecrypt(\n key: Uint8Array,\n iv: Uint8Array,\n ciphertext: Uint8Array,\n ): Promise<Uint8Array> {\n // Import the key for AES-CBC\n const cryptoKey = await crypto.subtle.importKey(\n \"raw\",\n key as BufferSource,\n { name: \"AES-CBC\" },\n false,\n [\"decrypt\"],\n );\n\n // Decrypt with Web Crypto API\n // Note: Web Crypto API automatically handles PKCS#7 padding removal\n const decrypted = await crypto.subtle.decrypt(\n { name: \"AES-CBC\", iv: iv as BufferSource },\n cryptoKey,\n ciphertext as BufferSource,\n );\n\n return new Uint8Array(decrypted);\n }\n\n /**\n * Normalizes a public key to uncompressed format (65 bytes with 0x04 prefix).\n * Handles compressed (33 bytes) and uncompressed (65 bytes) formats only.\n *\n * @remarks\n * Strict policy: Does not accept 64-byte raw coordinates to avoid masking\n * malformed data. Callers must provide properly formatted keys.\n *\n * @param publicKey - The public key to normalize (33 or 65 bytes)\n * @returns The normalized uncompressed public key (65 bytes)\n * @throws {Error} When public key format is invalid or decompression fails\n */\n normalizeToUncompressed(publicKey: Uint8Array): Uint8Array {\n const len = publicKey.length;\n\n // Already uncompressed\n if (len === 65 && publicKey[0] === 0x04) {\n return publicKey;\n }\n\n // Compressed - decompress using @noble/secp256k1\n if (len === 33 && (publicKey[0] === 0x02 || publicKey[0] === 0x03)) {\n const decompressed = this.decompressPublicKey(publicKey);\n if (!decompressed) {\n throw new Error(\n `Failed to decompress public key with prefix ${toHex(publicKey[0])}`,\n );\n }\n return decompressed;\n }\n\n // Reject raw coordinates (64 bytes) - require proper formatting\n if (len === 64) {\n throw new Error(\n \"Raw public key coordinates (64 bytes) are not accepted. \" +\n \"Please provide a properly formatted compressed (33 bytes) or uncompressed (65 bytes) public key.\",\n );\n }\n\n throw new Error(\n `Invalid public key format: expected compressed (33 bytes) or uncompressed (65 bytes), got ${len} bytes`,\n );\n }\n}\n"],"mappings":"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","names":["nobleSha512"]}
@@ -1,6 +1,3 @@
1
- import { BaseECIESUint8 } from './base.js';
2
- import './interface.js';
3
-
4
1
  /**
5
2
  * Browser implementation of ECIES using @noble/secp256k1 with Uint8Array
6
3
  *
@@ -8,7 +5,7 @@ import './interface.js';
8
5
  * Uses native browser crypto APIs and @noble/secp256k1 for elliptic curve operations.
9
6
  * This implementation is polyfill-free and works in all modern browsers.
10
7
  */
11
-
8
+ import { BaseECIESUint8 } from "./base";
12
9
  /**
13
10
  * Browser-specific ECIES provider using @noble/secp256k1
14
11
  *
@@ -19,7 +16,7 @@ import './interface.js';
19
16
  * - @noble/hashes for SHA and HMAC operations
20
17
  * - No Buffer or Node.js dependencies
21
18
  */
22
- declare class BrowserECIESUint8Provider extends BaseECIESUint8 {
19
+ export declare class BrowserECIESUint8Provider extends BaseECIESUint8 {
23
20
  protected generateRandomBytes(length: number): Uint8Array;
24
21
  protected verifyPrivateKey(privateKey: Uint8Array): boolean;
25
22
  protected createPublicKey(privateKey: Uint8Array, compressed: boolean): Uint8Array | null;
@@ -44,5 +41,3 @@ declare class BrowserECIESUint8Provider extends BaseECIESUint8 {
44
41
  */
45
42
  normalizeToUncompressed(publicKey: Uint8Array): Uint8Array;
46
43
  }
47
-
48
- export { BrowserECIESUint8Provider };
@@ -1,5 +1,6 @@
1
1
  import * as secp256k1 from "@noble/secp256k1";
2
2
  import { BaseECIESUint8 } from "./base";
3
+ import { toHex } from "viem";
3
4
  import { hmac } from "@noble/hashes/hmac";
4
5
  import { sha256, sha512 as nobleSha512 } from "@noble/hashes/sha2";
5
6
  class BrowserECIESUint8Provider extends BaseECIESUint8 {
@@ -109,7 +110,7 @@ class BrowserECIESUint8Provider extends BaseECIESUint8 {
109
110
  const decompressed = this.decompressPublicKey(publicKey);
110
111
  if (!decompressed) {
111
112
  throw new Error(
112
- `Failed to decompress public key with prefix 0x${publicKey[0].toString(16).padStart(2, "0")}`
113
+ `Failed to decompress public key with prefix ${toHex(publicKey[0])}`
113
114
  );
114
115
  }
115
116
  return decompressed;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/crypto/ecies/browser.ts"],"sourcesContent":["/**\n * Browser implementation of ECIES using @noble/secp256k1 with Uint8Array\n *\n * @remarks\n * Uses native browser crypto APIs and @noble/secp256k1 for elliptic curve operations.\n * This implementation is polyfill-free and works in all modern browsers.\n */\n\nimport * as secp256k1 from \"@noble/secp256k1\";\nimport { BaseECIESUint8 } from \"./base\";\nimport { hmac } from \"@noble/hashes/hmac\";\nimport { sha256, sha512 as nobleSha512 } from \"@noble/hashes/sha2\";\n\n/**\n * Browser-specific ECIES provider using @noble/secp256k1\n *\n * @remarks\n * This implementation uses:\n * - Web Crypto API for AES operations\n * - @noble/secp256k1 for elliptic curve operations\n * - @noble/hashes for SHA and HMAC operations\n * - No Buffer or Node.js dependencies\n */\nexport class BrowserECIESUint8Provider extends BaseECIESUint8 {\n protected generateRandomBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n crypto.getRandomValues(bytes);\n return bytes;\n }\n\n protected verifyPrivateKey(privateKey: Uint8Array): boolean {\n try {\n return secp256k1.utils.isValidPrivateKey(privateKey);\n } catch {\n return false;\n }\n }\n\n protected createPublicKey(\n privateKey: Uint8Array,\n compressed: boolean,\n ): Uint8Array | null {\n try {\n return secp256k1.getPublicKey(privateKey, compressed);\n } catch {\n return null;\n }\n }\n\n protected validatePublicKey(publicKey: Uint8Array): boolean {\n try {\n // @noble/secp256k1 will throw if the point is not on the curve\n secp256k1.Point.fromHex(publicKey);\n return true;\n } catch {\n return false;\n }\n }\n\n protected decompressPublicKey(publicKey: Uint8Array): Uint8Array | null {\n try {\n // @noble/secp256k1 handles both compressed and uncompressed\n const point = secp256k1.Point.fromHex(publicKey);\n return point.toRawBytes(false); // false = uncompressed\n } catch {\n return null;\n }\n }\n\n protected performECDH(\n publicKey: Uint8Array,\n privateKey: Uint8Array,\n ): Uint8Array {\n try {\n // Use @noble/secp256k1's getSharedSecret which is optimized and secure\n // The 'true' parameter returns the raw x-coordinate (32 bytes)\n // This matches eccrypto's behavior\n const sharedPoint = secp256k1.getSharedSecret(\n privateKey,\n publicKey,\n true,\n );\n\n // getSharedSecret returns compressed point (33 bytes) when true\n // We need just the x-coordinate (32 bytes) for eccrypto compatibility\n // Remove the prefix byte\n return sharedPoint.slice(1);\n } catch (error) {\n throw new Error(\n `ECDH failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n protected sha512(data: Uint8Array): Uint8Array {\n return nobleSha512(data);\n }\n\n protected hmacSha256(key: Uint8Array, data: Uint8Array): Uint8Array {\n return hmac(sha256, key, data);\n }\n\n protected async aesEncrypt(\n key: Uint8Array,\n iv: Uint8Array,\n plaintext: Uint8Array,\n ): Promise<Uint8Array> {\n // Import the key for AES-CBC\n const cryptoKey = await crypto.subtle.importKey(\n \"raw\",\n key as BufferSource,\n { name: \"AES-CBC\" },\n false,\n [\"encrypt\"],\n );\n\n // Encrypt with Web Crypto API\n // Note: Web Crypto API automatically handles PKCS#7 padding for AES-CBC\n const encrypted = await crypto.subtle.encrypt(\n { name: \"AES-CBC\", iv: iv as BufferSource },\n cryptoKey,\n plaintext as BufferSource,\n );\n\n return new Uint8Array(encrypted);\n }\n\n protected async aesDecrypt(\n key: Uint8Array,\n iv: Uint8Array,\n ciphertext: Uint8Array,\n ): Promise<Uint8Array> {\n // Import the key for AES-CBC\n const cryptoKey = await crypto.subtle.importKey(\n \"raw\",\n key as BufferSource,\n { name: \"AES-CBC\" },\n false,\n [\"decrypt\"],\n );\n\n // Decrypt with Web Crypto API\n // Note: Web Crypto API automatically handles PKCS#7 padding removal\n const decrypted = await crypto.subtle.decrypt(\n { name: \"AES-CBC\", iv: iv as BufferSource },\n cryptoKey,\n ciphertext as BufferSource,\n );\n\n return new Uint8Array(decrypted);\n }\n\n /**\n * Normalizes a public key to uncompressed format (65 bytes with 0x04 prefix).\n * Handles compressed (33 bytes) and uncompressed (65 bytes) formats only.\n *\n * @remarks\n * Strict policy: Does not accept 64-byte raw coordinates to avoid masking\n * malformed data. Callers must provide properly formatted keys.\n *\n * @param publicKey - The public key to normalize (33 or 65 bytes)\n * @returns The normalized uncompressed public key (65 bytes)\n * @throws {Error} When public key format is invalid or decompression fails\n */\n normalizeToUncompressed(publicKey: Uint8Array): Uint8Array {\n const len = publicKey.length;\n\n // Already uncompressed\n if (len === 65 && publicKey[0] === 0x04) {\n return publicKey;\n }\n\n // Compressed - decompress using @noble/secp256k1\n if (len === 33 && (publicKey[0] === 0x02 || publicKey[0] === 0x03)) {\n const decompressed = this.decompressPublicKey(publicKey);\n if (!decompressed) {\n throw new Error(\n `Failed to decompress public key with prefix 0x${publicKey[0].toString(16).padStart(2, \"0\")}`,\n );\n }\n return decompressed;\n }\n\n // Reject raw coordinates (64 bytes) - require proper formatting\n if (len === 64) {\n throw new Error(\n \"Raw public key coordinates (64 bytes) are not accepted. \" +\n \"Please provide a properly formatted compressed (33 bytes) or uncompressed (65 bytes) public key.\",\n );\n }\n\n throw new Error(\n `Invalid public key format: expected compressed (33 bytes) or uncompressed (65 bytes), got ${len} bytes`,\n );\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/crypto/ecies/browser.ts"],"sourcesContent":["/**\n * Browser implementation of ECIES using @noble/secp256k1 with Uint8Array\n *\n * @remarks\n * Uses native browser crypto APIs and @noble/secp256k1 for elliptic curve operations.\n * This implementation is polyfill-free and works in all modern browsers.\n */\n\nimport * as secp256k1 from \"@noble/secp256k1\";\nimport { BaseECIESUint8 } from \"./base\";\nimport { toHex } from \"viem\";\nimport { hmac } from \"@noble/hashes/hmac\";\nimport { sha256, sha512 as nobleSha512 } from \"@noble/hashes/sha2\";\n\n/**\n * Browser-specific ECIES provider using @noble/secp256k1\n *\n * @remarks\n * This implementation uses:\n * - Web Crypto API for AES operations\n * - @noble/secp256k1 for elliptic curve operations\n * - @noble/hashes for SHA and HMAC operations\n * - No Buffer or Node.js dependencies\n */\nexport class BrowserECIESUint8Provider extends BaseECIESUint8 {\n protected generateRandomBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n crypto.getRandomValues(bytes);\n return bytes;\n }\n\n protected verifyPrivateKey(privateKey: Uint8Array): boolean {\n try {\n return secp256k1.utils.isValidPrivateKey(privateKey);\n } catch {\n return false;\n }\n }\n\n protected createPublicKey(\n privateKey: Uint8Array,\n compressed: boolean,\n ): Uint8Array | null {\n try {\n return secp256k1.getPublicKey(privateKey, compressed);\n } catch {\n return null;\n }\n }\n\n protected validatePublicKey(publicKey: Uint8Array): boolean {\n try {\n // @noble/secp256k1 will throw if the point is not on the curve\n secp256k1.Point.fromHex(publicKey);\n return true;\n } catch {\n return false;\n }\n }\n\n protected decompressPublicKey(publicKey: Uint8Array): Uint8Array | null {\n try {\n // @noble/secp256k1 handles both compressed and uncompressed\n const point = secp256k1.Point.fromHex(publicKey);\n return point.toRawBytes(false); // false = uncompressed\n } catch {\n return null;\n }\n }\n\n protected performECDH(\n publicKey: Uint8Array,\n privateKey: Uint8Array,\n ): Uint8Array {\n try {\n // Use @noble/secp256k1's getSharedSecret which is optimized and secure\n // The 'true' parameter returns the raw x-coordinate (32 bytes)\n // This matches eccrypto's behavior\n const sharedPoint = secp256k1.getSharedSecret(\n privateKey,\n publicKey,\n true,\n );\n\n // getSharedSecret returns compressed point (33 bytes) when true\n // We need just the x-coordinate (32 bytes) for eccrypto compatibility\n // Remove the prefix byte\n return sharedPoint.slice(1);\n } catch (error) {\n throw new Error(\n `ECDH failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n protected sha512(data: Uint8Array): Uint8Array {\n return nobleSha512(data);\n }\n\n protected hmacSha256(key: Uint8Array, data: Uint8Array): Uint8Array {\n return hmac(sha256, key, data);\n }\n\n protected async aesEncrypt(\n key: Uint8Array,\n iv: Uint8Array,\n plaintext: Uint8Array,\n ): Promise<Uint8Array> {\n // Import the key for AES-CBC\n const cryptoKey = await crypto.subtle.importKey(\n \"raw\",\n key as BufferSource,\n { name: \"AES-CBC\" },\n false,\n [\"encrypt\"],\n );\n\n // Encrypt with Web Crypto API\n // Note: Web Crypto API automatically handles PKCS#7 padding for AES-CBC\n const encrypted = await crypto.subtle.encrypt(\n { name: \"AES-CBC\", iv: iv as BufferSource },\n cryptoKey,\n plaintext as BufferSource,\n );\n\n return new Uint8Array(encrypted);\n }\n\n protected async aesDecrypt(\n key: Uint8Array,\n iv: Uint8Array,\n ciphertext: Uint8Array,\n ): Promise<Uint8Array> {\n // Import the key for AES-CBC\n const cryptoKey = await crypto.subtle.importKey(\n \"raw\",\n key as BufferSource,\n { name: \"AES-CBC\" },\n false,\n [\"decrypt\"],\n );\n\n // Decrypt with Web Crypto API\n // Note: Web Crypto API automatically handles PKCS#7 padding removal\n const decrypted = await crypto.subtle.decrypt(\n { name: \"AES-CBC\", iv: iv as BufferSource },\n cryptoKey,\n ciphertext as BufferSource,\n );\n\n return new Uint8Array(decrypted);\n }\n\n /**\n * Normalizes a public key to uncompressed format (65 bytes with 0x04 prefix).\n * Handles compressed (33 bytes) and uncompressed (65 bytes) formats only.\n *\n * @remarks\n * Strict policy: Does not accept 64-byte raw coordinates to avoid masking\n * malformed data. Callers must provide properly formatted keys.\n *\n * @param publicKey - The public key to normalize (33 or 65 bytes)\n * @returns The normalized uncompressed public key (65 bytes)\n * @throws {Error} When public key format is invalid or decompression fails\n */\n normalizeToUncompressed(publicKey: Uint8Array): Uint8Array {\n const len = publicKey.length;\n\n // Already uncompressed\n if (len === 65 && publicKey[0] === 0x04) {\n return publicKey;\n }\n\n // Compressed - decompress using @noble/secp256k1\n if (len === 33 && (publicKey[0] === 0x02 || publicKey[0] === 0x03)) {\n const decompressed = this.decompressPublicKey(publicKey);\n if (!decompressed) {\n throw new Error(\n `Failed to decompress public key with prefix ${toHex(publicKey[0])}`,\n );\n }\n return decompressed;\n }\n\n // Reject raw coordinates (64 bytes) - require proper formatting\n if (len === 64) {\n throw new Error(\n \"Raw public key coordinates (64 bytes) are not accepted. \" +\n \"Please provide a properly formatted compressed (33 bytes) or uncompressed (65 bytes) public key.\",\n );\n }\n\n throw new Error(\n `Invalid public key format: expected compressed (33 bytes) or uncompressed (65 bytes), got ${len} bytes`,\n );\n }\n}\n"],"mappings":"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","names":[]}
@@ -8,7 +8,7 @@
8
8
  /**
9
9
  * Elliptic curve parameters
10
10
  */
11
- declare const CURVE: {
11
+ export declare const CURVE: {
12
12
  /** The elliptic curve used (secp256k1 - same as Bitcoin/Ethereum) */
13
13
  readonly name: "secp256k1";
14
14
  /** Private key length in bytes */
@@ -36,7 +36,7 @@ declare const CURVE: {
36
36
  /**
37
37
  * Symmetric encryption parameters (AES-256-CBC)
38
38
  */
39
- declare const CIPHER: {
39
+ export declare const CIPHER: {
40
40
  /** Cipher algorithm - must match eccrypto */
41
41
  readonly algorithm: "aes-256-cbc";
42
42
  /** AES key length in bytes */
@@ -49,7 +49,7 @@ declare const CIPHER: {
49
49
  /**
50
50
  * Key derivation function parameters
51
51
  */
52
- declare const KDF: {
52
+ export declare const KDF: {
53
53
  /** Hash algorithm for key derivation - must match eccrypto */
54
54
  readonly algorithm: "sha512";
55
55
  /** Output length of SHA-512 in bytes */
@@ -64,7 +64,7 @@ declare const KDF: {
64
64
  /**
65
65
  * Message authentication code parameters
66
66
  */
67
- declare const MAC: {
67
+ export declare const MAC: {
68
68
  /** MAC algorithm - must match eccrypto */
69
69
  readonly algorithm: "sha256";
70
70
  /** HMAC-SHA256 output length in bytes */
@@ -74,7 +74,7 @@ declare const MAC: {
74
74
  * ECIES encrypted data format offsets and lengths
75
75
  * Format: [iv(16)][ephemPublicKey(65)][ciphertext(variable)][mac(32)]
76
76
  */
77
- declare const FORMAT: {
77
+ export declare const FORMAT: {
78
78
  /** Offsets for each component in serialized format */
79
79
  readonly IV_OFFSET: 0;
80
80
  readonly IV_LENGTH: 16;
@@ -98,7 +98,7 @@ declare const FORMAT: {
98
98
  /**
99
99
  * Security constants for data clearing
100
100
  */
101
- declare const SECURITY: {
101
+ export declare const SECURITY: {
102
102
  /** Overwrite patterns for secure data clearing */
103
103
  readonly CLEAR_PATTERNS: {
104
104
  readonly ZEROS: 0;
@@ -112,11 +112,9 @@ declare const SECURITY: {
112
112
  /**
113
113
  * Validation helpers
114
114
  */
115
- declare const VALIDATION: {
115
+ export declare const VALIDATION: {
116
116
  readonly isValidPrivateKey: (key: Uint8Array) => boolean;
117
117
  readonly isValidPublicKey: (key: Uint8Array) => boolean;
118
118
  readonly isCompressedPublicKey: (key: Uint8Array) => boolean;
119
119
  readonly isUncompressedPublicKey: (key: Uint8Array) => boolean;
120
120
  };
121
-
122
- export { CIPHER, CURVE, FORMAT, KDF, MAC, SECURITY, VALIDATION };
@@ -1 +1,8 @@
1
- export { ECIESEncrypted, ECIESError, ECIESOptions, ECIESProvider, deserializeECIES, isECIESEncrypted, serializeECIES } from './interface.js';
1
+ /**
2
+ * ECIES Module Entry Point
3
+ *
4
+ * Exports interface and utilities for ECIES encryption/decryption
5
+ * Platform-specific implementations are imported separately
6
+ */
7
+ export type { ECIESProvider, ECIESEncrypted, ECIESOptions } from "./interface";
8
+ export { ECIESError, isECIESEncrypted, serializeECIES, deserializeECIES, } from "./interface";
@@ -25,6 +25,7 @@ __export(interface_exports, {
25
25
  });
26
26
  module.exports = __toCommonJS(interface_exports);
27
27
  var import_constants = require("./constants");
28
+ var import_viem = require("viem");
28
29
  class ECIESError extends Error {
29
30
  constructor(message, code, cause) {
30
31
  super(message);
@@ -53,13 +54,11 @@ function serializeECIES(encrypted) {
53
54
  combined.set(encrypted.ciphertext, offset);
54
55
  offset += encrypted.ciphertext.length;
55
56
  combined.set(encrypted.mac, offset);
56
- return Array.from(combined).map((b) => b.toString(16).padStart(2, "0")).join("");
57
+ return (0, import_viem.toHex)(combined).slice(2);
57
58
  }
58
59
  function deserializeECIES(hex) {
59
- const bytes = new Uint8Array(hex.length / 2);
60
- for (let i = 0; i < hex.length; i += 2) {
61
- bytes[i / 2] = parseInt(hex.substr(i, 2), 16);
62
- }
60
+ const hexWithPrefix = hex.startsWith("0x") ? hex : `0x${hex}`;
61
+ const bytes = (0, import_viem.fromHex)(hexWithPrefix, "bytes");
63
62
  const ephemKeySize = bytes[import_constants.FORMAT.EPHEMERAL_KEY_OFFSET] === import_constants.CURVE.PREFIX.UNCOMPRESSED ? import_constants.CURVE.UNCOMPRESSED_PUBLIC_KEY_LENGTH : import_constants.CURVE.COMPRESSED_PUBLIC_KEY_LENGTH;
64
63
  const minLength = import_constants.FORMAT.IV_LENGTH + ephemKeySize + import_constants.MAC.LENGTH + 1;
65
64
  if (bytes.length < minLength) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/crypto/ecies/interface.ts"],"sourcesContent":["/**\n * ECIES (Elliptic Curve Integrated Encryption Scheme) Interface\n *\n * @remarks\n * Defines the contract for platform-specific ECIES implementations.\n * All implementations maintain compatibility with the eccrypto format to ensure\n * backward compatibility with existing encrypted data.\n *\n * **Format specification:**\n * `[iv (16 bytes)][ephemPublicKey (65 bytes)][ciphertext (variable)][mac (32 bytes)]`\n *\n * @category Cryptography\n */\n\nimport { CIPHER, CURVE, MAC, FORMAT } from \"./constants\";\n\n/**\n * Represents ECIES encrypted data in eccrypto-compatible format.\n *\n * @remarks\n * This structure maintains backward compatibility with data encrypted using\n * the legacy eccrypto library.\n */\nexport interface ECIESEncrypted {\n /** Initialization vector (16 bytes) */\n iv: Uint8Array;\n /** Ephemeral public key (65 bytes uncompressed) */\n ephemPublicKey: Uint8Array;\n /** Encrypted data */\n ciphertext: Uint8Array;\n /** Message authentication code (32 bytes) */\n mac: Uint8Array;\n}\n\n/**\n * Provides ECIES encryption and decryption operations.\n *\n * @remarks\n * Platform-specific implementations handle the underlying cryptographic primitives\n * while maintaining consistent data format across environments.\n *\n * @category Cryptography\n */\nexport interface ECIESProvider {\n /**\n * Encrypts data using ECIES with secp256k1.\n *\n * @param publicKey - Recipient's public key (65 bytes uncompressed or 33 bytes compressed).\n * Obtain via `vana.server.getIdentity(userAddress).public_key`.\n * @param message - Data to encrypt.\n * @returns Encrypted data structure compatible with eccrypto format.\n * @throws {ECIESError} When public key is invalid.\n * Verify key format matches secp256k1 requirements.\n *\n * @example\n * ```typescript\n * const encrypted = await provider.encrypt(\n * hexToBytes(publicKey),\n * new TextEncoder().encode('sensitive data')\n * );\n * ```\n */\n encrypt(publicKey: Uint8Array, message: Uint8Array): Promise<ECIESEncrypted>;\n\n /**\n * Decrypts ECIES encrypted data.\n *\n * @param privateKey - Recipient's private key (32 bytes).\n * @param encrypted - Encrypted data structure from `encrypt()` or legacy eccrypto.\n * @returns Decrypted message as Uint8Array.\n * @throws {ECIESError} When MAC verification fails.\n * Ensure the private key matches the public key used for encryption.\n *\n * @example\n * ```typescript\n * const decrypted = await provider.decrypt(\n * hexToBytes(privateKey),\n * encrypted\n * );\n * const message = new TextDecoder().decode(decrypted);\n * ```\n */\n decrypt(\n privateKey: Uint8Array,\n encrypted: ECIESEncrypted,\n ): Promise<Uint8Array>;\n\n /**\n * Normalizes a public key to uncompressed format (65 bytes with 0x04 prefix).\n *\n * @remarks\n * Strict policy: Only accepts properly formatted compressed (33 bytes) or\n * uncompressed (65 bytes) public keys. Does not accept 64-byte raw coordinates\n * to ensure data integrity and prevent masking of malformed inputs.\n *\n * @param publicKey - Public key in compressed or uncompressed format\n * @returns Normalized uncompressed public key (65 bytes with 0x04 prefix)\n * @throws {Error} When public key format is invalid, including raw coordinates (64 bytes)\n * @throws {Error} When decompression of compressed key fails\n *\n * @example\n * ```typescript\n * // Compressed key (33 bytes)\n * const compressed = new Uint8Array(33);\n * compressed[0] = 0x02;\n * const uncompressed = provider.normalizeToUncompressed(compressed);\n * console.log(uncompressed.length); // 65\n * console.log(uncompressed[0]); // 0x04\n *\n * // Already uncompressed (65 bytes)\n * const already = provider.normalizeToUncompressed(uncompressedKey);\n * console.log(already === uncompressedKey); // true (returns same reference)\n *\n * // Raw coordinates rejected (64 bytes)\n * const raw = new Uint8Array(64);\n * provider.normalizeToUncompressed(raw); // Throws error\n * ```\n */\n normalizeToUncompressed(publicKey: Uint8Array): Uint8Array;\n}\n\n/**\n * Configures ECIES operation behavior.\n */\nexport interface ECIESOptions {\n /** Use compressed public keys (33 bytes) instead of uncompressed (65 bytes) */\n useCompressed?: boolean;\n}\n\n/**\n * Represents failures in ECIES cryptographic operations.\n *\n * @remarks\n * Provides specific error codes to help identify and recover from\n * different failure scenarios.\n *\n * @category Errors\n */\nexport class ECIESError extends Error {\n constructor(\n message: string,\n public readonly code:\n | \"INVALID_KEY\"\n | \"ENCRYPTION_FAILED\"\n | \"DECRYPTION_FAILED\"\n | \"MAC_MISMATCH\"\n | \"ECDH_FAILED\",\n public override readonly cause?: Error,\n ) {\n super(message);\n this.name = \"ECIESError\";\n }\n}\n\n/**\n * Validates if an object conforms to the ECIESEncrypted structure.\n *\n * @param obj - Object to validate.\n * @returns `true` if object is a valid ECIESEncrypted structure.\n *\n * @example\n * ```typescript\n * if (isECIESEncrypted(data)) {\n * const decrypted = await provider.decrypt(privateKey, data);\n * }\n * ```\n */\nexport function isECIESEncrypted(obj: unknown): obj is ECIESEncrypted {\n if (!obj || typeof obj !== \"object\") return false;\n const enc = obj as Record<string, unknown>;\n\n const isUint8Array = (value: unknown): value is Uint8Array => {\n return (\n value instanceof Uint8Array ||\n (typeof Buffer !== \"undefined\" && Buffer.isBuffer(value))\n );\n };\n\n return (\n isUint8Array(enc.iv) &&\n enc.iv.length === CIPHER.IV_LENGTH &&\n isUint8Array(enc.ephemPublicKey) &&\n (enc.ephemPublicKey.length === CURVE.UNCOMPRESSED_PUBLIC_KEY_LENGTH ||\n enc.ephemPublicKey.length === CURVE.COMPRESSED_PUBLIC_KEY_LENGTH) &&\n isUint8Array(enc.ciphertext) &&\n enc.ciphertext.length > 0 &&\n isUint8Array(enc.mac) &&\n enc.mac.length === MAC.LENGTH\n );\n}\n\n/**\n * Serializes ECIESEncrypted to hex string for storage or transmission.\n *\n * @param encrypted - Encrypted data structure from `encrypt()`.\n * @returns Hex string representation.\n *\n * @example\n * ```typescript\n * const hexString = serializeECIES(encrypted);\n * // Store hexString in database or send over network\n * ```\n */\nexport function serializeECIES(encrypted: ECIESEncrypted): string {\n const combined = new Uint8Array(\n encrypted.iv.length +\n encrypted.ephemPublicKey.length +\n encrypted.ciphertext.length +\n encrypted.mac.length,\n );\n\n let offset = 0;\n combined.set(encrypted.iv, offset);\n offset += encrypted.iv.length;\n combined.set(encrypted.ephemPublicKey, offset);\n offset += encrypted.ephemPublicKey.length;\n combined.set(encrypted.ciphertext, offset);\n offset += encrypted.ciphertext.length;\n combined.set(encrypted.mac, offset);\n\n return Array.from(combined)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n/**\n * Deserializes hex string to ECIESEncrypted structure.\n *\n * @param hex - Hex string from `serializeECIES()` or storage.\n * @returns ECIESEncrypted structure ready for decryption.\n * @throws {ECIESError} When hex string format is invalid.\n * Verify the hex string is complete and uncorrupted.\n *\n * @example\n * ```typescript\n * const encrypted = deserializeECIES(hexString);\n * const decrypted = await provider.decrypt(privateKey, encrypted);\n * ```\n */\nexport function deserializeECIES(hex: string): ECIESEncrypted {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n bytes[i / 2] = parseInt(hex.substr(i, 2), 16);\n }\n\n // Determine ephemPublicKey size based on prefix\n const ephemKeySize =\n bytes[FORMAT.EPHEMERAL_KEY_OFFSET] === CURVE.PREFIX.UNCOMPRESSED\n ? CURVE.UNCOMPRESSED_PUBLIC_KEY_LENGTH\n : CURVE.COMPRESSED_PUBLIC_KEY_LENGTH;\n\n const minLength = FORMAT.IV_LENGTH + ephemKeySize + MAC.LENGTH + 1; // +1 for at least 1 byte of ciphertext\n if (bytes.length < minLength) {\n throw new ECIESError(\"Invalid ECIES data: too short\", \"DECRYPTION_FAILED\");\n }\n\n return {\n iv: bytes.subarray(FORMAT.IV_OFFSET, FORMAT.IV_OFFSET + FORMAT.IV_LENGTH),\n ephemPublicKey: bytes.subarray(\n FORMAT.EPHEMERAL_KEY_OFFSET,\n FORMAT.EPHEMERAL_KEY_OFFSET + ephemKeySize,\n ),\n ciphertext: bytes.subarray(\n FORMAT.EPHEMERAL_KEY_OFFSET + ephemKeySize,\n bytes.length - MAC.LENGTH,\n ),\n mac: bytes.subarray(bytes.length - MAC.LENGTH),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcA,uBAA2C;AA4HpC,MAAM,mBAAmB,MAAM;AAAA,EACpC,YACE,SACgB,MAMS,OACzB;AACA,UAAM,OAAO;AARG;AAMS;AAGzB,SAAK,OAAO;AAAA,EACd;AACF;AAeO,SAAS,iBAAiB,KAAqC;AACpE,MAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO;AAC5C,QAAM,MAAM;AAEZ,QAAM,eAAe,CAAC,UAAwC;AAC5D,WACE,iBAAiB,cAChB,OAAO,WAAW,eAAe,OAAO,SAAS,KAAK;AAAA,EAE3D;AAEA,SACE,aAAa,IAAI,EAAE,KACnB,IAAI,GAAG,WAAW,wBAAO,aACzB,aAAa,IAAI,cAAc,MAC9B,IAAI,eAAe,WAAW,uBAAM,kCACnC,IAAI,eAAe,WAAW,uBAAM,iCACtC,aAAa,IAAI,UAAU,KAC3B,IAAI,WAAW,SAAS,KACxB,aAAa,IAAI,GAAG,KACpB,IAAI,IAAI,WAAW,qBAAI;AAE3B;AAcO,SAAS,eAAe,WAAmC;AAChE,QAAM,WAAW,IAAI;AAAA,IACnB,UAAU,GAAG,SACX,UAAU,eAAe,SACzB,UAAU,WAAW,SACrB,UAAU,IAAI;AAAA,EAClB;AAEA,MAAI,SAAS;AACb,WAAS,IAAI,UAAU,IAAI,MAAM;AACjC,YAAU,UAAU,GAAG;AACvB,WAAS,IAAI,UAAU,gBAAgB,MAAM;AAC7C,YAAU,UAAU,eAAe;AACnC,WAAS,IAAI,UAAU,YAAY,MAAM;AACzC,YAAU,UAAU,WAAW;AAC/B,WAAS,IAAI,UAAU,KAAK,MAAM;AAElC,SAAO,MAAM,KAAK,QAAQ,EACvB,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAC1C,KAAK,EAAE;AACZ;AAgBO,SAAS,iBAAiB,KAA6B;AAC5D,QAAM,QAAQ,IAAI,WAAW,IAAI,SAAS,CAAC;AAC3C,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK,GAAG;AACtC,UAAM,IAAI,CAAC,IAAI,SAAS,IAAI,OAAO,GAAG,CAAC,GAAG,EAAE;AAAA,EAC9C;AAGA,QAAM,eACJ,MAAM,wBAAO,oBAAoB,MAAM,uBAAM,OAAO,eAChD,uBAAM,iCACN,uBAAM;AAEZ,QAAM,YAAY,wBAAO,YAAY,eAAe,qBAAI,SAAS;AACjE,MAAI,MAAM,SAAS,WAAW;AAC5B,UAAM,IAAI,WAAW,iCAAiC,mBAAmB;AAAA,EAC3E;AAEA,SAAO;AAAA,IACL,IAAI,MAAM,SAAS,wBAAO,WAAW,wBAAO,YAAY,wBAAO,SAAS;AAAA,IACxE,gBAAgB,MAAM;AAAA,MACpB,wBAAO;AAAA,MACP,wBAAO,uBAAuB;AAAA,IAChC;AAAA,IACA,YAAY,MAAM;AAAA,MAChB,wBAAO,uBAAuB;AAAA,MAC9B,MAAM,SAAS,qBAAI;AAAA,IACrB;AAAA,IACA,KAAK,MAAM,SAAS,MAAM,SAAS,qBAAI,MAAM;AAAA,EAC/C;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/crypto/ecies/interface.ts"],"sourcesContent":["/**\n * ECIES (Elliptic Curve Integrated Encryption Scheme) Interface\n *\n * @remarks\n * Defines the contract for platform-specific ECIES implementations.\n * All implementations maintain compatibility with the eccrypto format to ensure\n * backward compatibility with existing encrypted data.\n *\n * **Format specification:**\n * `[iv (16 bytes)][ephemPublicKey (65 bytes)][ciphertext (variable)][mac (32 bytes)]`\n *\n * @category Cryptography\n */\n\nimport { CIPHER, CURVE, MAC, FORMAT } from \"./constants\";\nimport { fromHex, toHex } from \"viem\";\n\n/**\n * Represents ECIES encrypted data in eccrypto-compatible format.\n *\n * @remarks\n * This structure maintains backward compatibility with data encrypted using\n * the legacy eccrypto library.\n */\nexport interface ECIESEncrypted {\n /** Initialization vector (16 bytes) */\n iv: Uint8Array;\n /** Ephemeral public key (65 bytes uncompressed) */\n ephemPublicKey: Uint8Array;\n /** Encrypted data */\n ciphertext: Uint8Array;\n /** Message authentication code (32 bytes) */\n mac: Uint8Array;\n}\n\n/**\n * Provides ECIES encryption and decryption operations.\n *\n * @remarks\n * Platform-specific implementations handle the underlying cryptographic primitives\n * while maintaining consistent data format across environments.\n *\n * @category Cryptography\n */\nexport interface ECIESProvider {\n /**\n * Encrypts data using ECIES with secp256k1.\n *\n * @param publicKey - Recipient's public key (65 bytes uncompressed or 33 bytes compressed).\n * Obtain via `vana.server.getIdentity(userAddress).public_key`.\n * @param message - Data to encrypt.\n * @returns Encrypted data structure compatible with eccrypto format.\n * @throws {ECIESError} When public key is invalid.\n * Verify key format matches secp256k1 requirements.\n *\n * @example\n * ```typescript\n * const encrypted = await provider.encrypt(\n * fromHex(publicKey, 'bytes'),\n * new TextEncoder().encode('sensitive data')\n * );\n * ```\n */\n encrypt(publicKey: Uint8Array, message: Uint8Array): Promise<ECIESEncrypted>;\n\n /**\n * Decrypts ECIES encrypted data.\n *\n * @param privateKey - Recipient's private key (32 bytes).\n * @param encrypted - Encrypted data structure from `encrypt()` or legacy eccrypto.\n * @returns Decrypted message as Uint8Array.\n * @throws {ECIESError} When MAC verification fails.\n * Ensure the private key matches the public key used for encryption.\n *\n * @example\n * ```typescript\n * const decrypted = await provider.decrypt(\n * fromHex(privateKey, 'bytes'),\n * encrypted\n * );\n * const message = new TextDecoder().decode(decrypted);\n * ```\n */\n decrypt(\n privateKey: Uint8Array,\n encrypted: ECIESEncrypted,\n ): Promise<Uint8Array>;\n\n /**\n * Normalizes a public key to uncompressed format (65 bytes with 0x04 prefix).\n *\n * @remarks\n * Strict policy: Only accepts properly formatted compressed (33 bytes) or\n * uncompressed (65 bytes) public keys. Does not accept 64-byte raw coordinates\n * to ensure data integrity and prevent masking of malformed inputs.\n *\n * @param publicKey - Public key in compressed or uncompressed format\n * @returns Normalized uncompressed public key (65 bytes with 0x04 prefix)\n * @throws {Error} When public key format is invalid, including raw coordinates (64 bytes)\n * @throws {Error} When decompression of compressed key fails\n *\n * @example\n * ```typescript\n * // Compressed key (33 bytes)\n * const compressed = new Uint8Array(33);\n * compressed[0] = 0x02;\n * const uncompressed = provider.normalizeToUncompressed(compressed);\n * console.log(uncompressed.length); // 65\n * console.log(uncompressed[0]); // 0x04\n *\n * // Already uncompressed (65 bytes)\n * const already = provider.normalizeToUncompressed(uncompressedKey);\n * console.log(already === uncompressedKey); // true (returns same reference)\n *\n * // Raw coordinates rejected (64 bytes)\n * const raw = new Uint8Array(64);\n * provider.normalizeToUncompressed(raw); // Throws error\n * ```\n */\n normalizeToUncompressed(publicKey: Uint8Array): Uint8Array;\n}\n\n/**\n * Configures ECIES operation behavior.\n */\nexport interface ECIESOptions {\n /** Use compressed public keys (33 bytes) instead of uncompressed (65 bytes) */\n useCompressed?: boolean;\n}\n\n/**\n * Represents failures in ECIES cryptographic operations.\n *\n * @remarks\n * Provides specific error codes to help identify and recover from\n * different failure scenarios.\n *\n * @category Errors\n */\nexport class ECIESError extends Error {\n constructor(\n message: string,\n public readonly code:\n | \"INVALID_KEY\"\n | \"ENCRYPTION_FAILED\"\n | \"DECRYPTION_FAILED\"\n | \"MAC_MISMATCH\"\n | \"ECDH_FAILED\",\n public override readonly cause?: Error,\n ) {\n super(message);\n this.name = \"ECIESError\";\n }\n}\n\n/**\n * Validates if an object conforms to the ECIESEncrypted structure.\n *\n * @param obj - Object to validate.\n * @returns `true` if object is a valid ECIESEncrypted structure.\n *\n * @example\n * ```typescript\n * if (isECIESEncrypted(data)) {\n * const decrypted = await provider.decrypt(privateKey, data);\n * }\n * ```\n */\nexport function isECIESEncrypted(obj: unknown): obj is ECIESEncrypted {\n if (!obj || typeof obj !== \"object\") return false;\n const enc = obj as Record<string, unknown>;\n\n const isUint8Array = (value: unknown): value is Uint8Array => {\n return (\n value instanceof Uint8Array ||\n (typeof Buffer !== \"undefined\" && Buffer.isBuffer(value))\n );\n };\n\n return (\n isUint8Array(enc.iv) &&\n enc.iv.length === CIPHER.IV_LENGTH &&\n isUint8Array(enc.ephemPublicKey) &&\n (enc.ephemPublicKey.length === CURVE.UNCOMPRESSED_PUBLIC_KEY_LENGTH ||\n enc.ephemPublicKey.length === CURVE.COMPRESSED_PUBLIC_KEY_LENGTH) &&\n isUint8Array(enc.ciphertext) &&\n enc.ciphertext.length > 0 &&\n isUint8Array(enc.mac) &&\n enc.mac.length === MAC.LENGTH\n );\n}\n\n/**\n * Serializes ECIESEncrypted to hex string for storage or transmission.\n *\n * @param encrypted - Encrypted data structure from `encrypt()`.\n * @returns Hex string representation.\n *\n * @example\n * ```typescript\n * const hexString = serializeECIES(encrypted);\n * // Store hexString in database or send over network\n * ```\n */\nexport function serializeECIES(encrypted: ECIESEncrypted): string {\n const combined = new Uint8Array(\n encrypted.iv.length +\n encrypted.ephemPublicKey.length +\n encrypted.ciphertext.length +\n encrypted.mac.length,\n );\n\n let offset = 0;\n combined.set(encrypted.iv, offset);\n offset += encrypted.iv.length;\n combined.set(encrypted.ephemPublicKey, offset);\n offset += encrypted.ephemPublicKey.length;\n combined.set(encrypted.ciphertext, offset);\n offset += encrypted.ciphertext.length;\n combined.set(encrypted.mac, offset);\n\n return toHex(combined).slice(2);\n}\n\n/**\n * Deserializes hex string to ECIESEncrypted structure.\n *\n * @param hex - Hex string from `serializeECIES()` or storage.\n * @returns ECIESEncrypted structure ready for decryption.\n * @throws {ECIESError} When hex string format is invalid.\n * Verify the hex string is complete and uncorrupted.\n *\n * @example\n * ```typescript\n * const encrypted = deserializeECIES(hexString);\n * const decrypted = await provider.decrypt(privateKey, encrypted);\n * ```\n */\nexport function deserializeECIES(hex: string): ECIESEncrypted {\n const hexWithPrefix = hex.startsWith(\"0x\") ? hex : `0x${hex}`;\n const bytes = fromHex(hexWithPrefix as `0x${string}`, \"bytes\");\n\n // Determine ephemPublicKey size based on prefix\n const ephemKeySize =\n bytes[FORMAT.EPHEMERAL_KEY_OFFSET] === CURVE.PREFIX.UNCOMPRESSED\n ? CURVE.UNCOMPRESSED_PUBLIC_KEY_LENGTH\n : CURVE.COMPRESSED_PUBLIC_KEY_LENGTH;\n\n const minLength = FORMAT.IV_LENGTH + ephemKeySize + MAC.LENGTH + 1; // +1 for at least 1 byte of ciphertext\n if (bytes.length < minLength) {\n throw new ECIESError(\"Invalid ECIES data: too short\", \"DECRYPTION_FAILED\");\n }\n\n return {\n iv: bytes.subarray(FORMAT.IV_OFFSET, FORMAT.IV_OFFSET + FORMAT.IV_LENGTH),\n ephemPublicKey: bytes.subarray(\n FORMAT.EPHEMERAL_KEY_OFFSET,\n FORMAT.EPHEMERAL_KEY_OFFSET + ephemKeySize,\n ),\n ciphertext: bytes.subarray(\n FORMAT.EPHEMERAL_KEY_OFFSET + ephemKeySize,\n bytes.length - MAC.LENGTH,\n ),\n mac: bytes.subarray(bytes.length - MAC.LENGTH),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcA,uBAA2C;AAC3C,kBAA+B;AA4HxB,MAAM,mBAAmB,MAAM;AAAA,EACpC,YACE,SACgB,MAMS,OACzB;AACA,UAAM,OAAO;AARG;AAMS;AAGzB,SAAK,OAAO;AAAA,EACd;AACF;AAeO,SAAS,iBAAiB,KAAqC;AACpE,MAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO;AAC5C,QAAM,MAAM;AAEZ,QAAM,eAAe,CAAC,UAAwC;AAC5D,WACE,iBAAiB,cAChB,OAAO,WAAW,eAAe,OAAO,SAAS,KAAK;AAAA,EAE3D;AAEA,SACE,aAAa,IAAI,EAAE,KACnB,IAAI,GAAG,WAAW,wBAAO,aACzB,aAAa,IAAI,cAAc,MAC9B,IAAI,eAAe,WAAW,uBAAM,kCACnC,IAAI,eAAe,WAAW,uBAAM,iCACtC,aAAa,IAAI,UAAU,KAC3B,IAAI,WAAW,SAAS,KACxB,aAAa,IAAI,GAAG,KACpB,IAAI,IAAI,WAAW,qBAAI;AAE3B;AAcO,SAAS,eAAe,WAAmC;AAChE,QAAM,WAAW,IAAI;AAAA,IACnB,UAAU,GAAG,SACX,UAAU,eAAe,SACzB,UAAU,WAAW,SACrB,UAAU,IAAI;AAAA,EAClB;AAEA,MAAI,SAAS;AACb,WAAS,IAAI,UAAU,IAAI,MAAM;AACjC,YAAU,UAAU,GAAG;AACvB,WAAS,IAAI,UAAU,gBAAgB,MAAM;AAC7C,YAAU,UAAU,eAAe;AACnC,WAAS,IAAI,UAAU,YAAY,MAAM;AACzC,YAAU,UAAU,WAAW;AAC/B,WAAS,IAAI,UAAU,KAAK,MAAM;AAElC,aAAO,mBAAM,QAAQ,EAAE,MAAM,CAAC;AAChC;AAgBO,SAAS,iBAAiB,KAA6B;AAC5D,QAAM,gBAAgB,IAAI,WAAW,IAAI,IAAI,MAAM,KAAK,GAAG;AAC3D,QAAM,YAAQ,qBAAQ,eAAgC,OAAO;AAG7D,QAAM,eACJ,MAAM,wBAAO,oBAAoB,MAAM,uBAAM,OAAO,eAChD,uBAAM,iCACN,uBAAM;AAEZ,QAAM,YAAY,wBAAO,YAAY,eAAe,qBAAI,SAAS;AACjE,MAAI,MAAM,SAAS,WAAW;AAC5B,UAAM,IAAI,WAAW,iCAAiC,mBAAmB;AAAA,EAC3E;AAEA,SAAO;AAAA,IACL,IAAI,MAAM,SAAS,wBAAO,WAAW,wBAAO,YAAY,wBAAO,SAAS;AAAA,IACxE,gBAAgB,MAAM;AAAA,MACpB,wBAAO;AAAA,MACP,wBAAO,uBAAuB;AAAA,IAChC;AAAA,IACA,YAAY,MAAM;AAAA,MAChB,wBAAO,uBAAuB;AAAA,MAC9B,MAAM,SAAS,qBAAI;AAAA,IACrB;AAAA,IACA,KAAK,MAAM,SAAS,MAAM,SAAS,qBAAI,MAAM;AAAA,EAC/C;AACF;","names":[]}