@primuslabs/fhetransform-sdk 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (302) hide show
  1. package/README.md +198 -0
  2. package/dist/abis/acl.abi.d.ts +379 -0
  3. package/dist/abis/acl.abi.js +495 -0
  4. package/dist/abis/acl.abi.js.map +1 -0
  5. package/dist/abis/alphatrion_reward.abi.d.ts +407 -0
  6. package/dist/abis/alphatrion_reward.abi.js +532 -0
  7. package/dist/abis/alphatrion_reward.abi.js.map +1 -0
  8. package/dist/abis/ciphertext_digests.abi.d.ts +336 -0
  9. package/dist/abis/ciphertext_digests.abi.js +444 -0
  10. package/dist/abis/ciphertext_digests.abi.js.map +1 -0
  11. package/dist/abis/ciphertext_verification.abi.d.ts +637 -0
  12. package/dist/abis/ciphertext_verification.abi.js +830 -0
  13. package/dist/abis/ciphertext_verification.abi.js.map +1 -0
  14. package/dist/abis/convert_token.abi.d.ts +922 -0
  15. package/dist/abis/convert_token.abi.js +1208 -0
  16. package/dist/abis/convert_token.abi.js.map +1 -0
  17. package/dist/abis/decryption.abi.d.ts +956 -0
  18. package/dist/abis/decryption.abi.js +1244 -0
  19. package/dist/abis/decryption.abi.js.map +1 -0
  20. package/dist/abis/erc20.abi.d.ts +265 -0
  21. package/dist/abis/erc20.abi.js +350 -0
  22. package/dist/abis/erc20.abi.js.map +1 -0
  23. package/dist/abis/fhe_executor.abi.d.ts +1535 -0
  24. package/dist/abis/fhe_executor.abi.js +1962 -0
  25. package/dist/abis/fhe_executor.abi.js.map +1 -0
  26. package/dist/abis/space_bridge_config.abi.d.ts +792 -0
  27. package/dist/abis/space_bridge_config.abi.js +1032 -0
  28. package/dist/abis/space_bridge_config.abi.js.map +1 -0
  29. package/dist/abis/token.abi.d.ts +630 -0
  30. package/dist/abis/token.abi.js +828 -0
  31. package/dist/abis/token.abi.js.map +1 -0
  32. package/dist/cli/eusdc.d.ts +2 -0
  33. package/dist/cli/eusdc.js +41 -0
  34. package/dist/cli/eusdc.js.map +1 -0
  35. package/dist/contract/callbacks.d.ts +59 -0
  36. package/dist/contract/callbacks.js +2 -0
  37. package/dist/contract/callbacks.js.map +1 -0
  38. package/dist/contract/convert-token.d.ts +107 -0
  39. package/dist/contract/convert-token.js +249 -0
  40. package/dist/contract/convert-token.js.map +1 -0
  41. package/dist/contract/token.d.ts +167 -0
  42. package/dist/contract/token.js +404 -0
  43. package/dist/contract/token.js.map +1 -0
  44. package/dist/contract/transaction.d.ts +29 -0
  45. package/dist/contract/transaction.js +2 -0
  46. package/dist/contract/transaction.js.map +1 -0
  47. package/dist/core/address.d.ts +118 -0
  48. package/dist/core/address.js +200 -0
  49. package/dist/core/address.js.map +1 -0
  50. package/dist/core/auth.d.ts +68 -0
  51. package/dist/core/auth.js +58 -0
  52. package/dist/core/auth.js.map +1 -0
  53. package/dist/core/bytes.d.ts +48 -0
  54. package/dist/core/bytes.js +117 -0
  55. package/dist/core/bytes.js.map +1 -0
  56. package/dist/core/cache-manager.d.ts +138 -0
  57. package/dist/core/cache-manager.js +440 -0
  58. package/dist/core/cache-manager.js.map +1 -0
  59. package/dist/core/chain.d.ts +41 -0
  60. package/dist/core/chain.js +59 -0
  61. package/dist/core/chain.js.map +1 -0
  62. package/dist/core/constants.d.ts +24 -0
  63. package/dist/core/constants.js +25 -0
  64. package/dist/core/constants.js.map +1 -0
  65. package/dist/core/error.d.ts +2 -0
  66. package/dist/core/error.js +14 -0
  67. package/dist/core/error.js.map +1 -0
  68. package/dist/core/errors/error-catalog.d.ts +29 -0
  69. package/dist/core/errors/error-catalog.js +84 -0
  70. package/dist/core/errors/error-catalog.js.map +1 -0
  71. package/dist/core/errors/error-codes.d.ts +52 -0
  72. package/dist/core/errors/error-codes.js +61 -0
  73. package/dist/core/errors/error-codes.js.map +1 -0
  74. package/dist/core/errors/error-utils.d.ts +27 -0
  75. package/dist/core/errors/error-utils.js +110 -0
  76. package/dist/core/errors/error-utils.js.map +1 -0
  77. package/dist/core/errors/fhe-error.d.ts +98 -0
  78. package/dist/core/errors/fhe-error.js +190 -0
  79. package/dist/core/errors/fhe-error.js.map +1 -0
  80. package/dist/core/errors/index.d.ts +4 -0
  81. package/dist/core/errors/index.js +5 -0
  82. package/dist/core/errors/index.js.map +1 -0
  83. package/dist/core/estimate.d.ts +39 -0
  84. package/dist/core/estimate.js +111 -0
  85. package/dist/core/estimate.js.map +1 -0
  86. package/dist/core/event.d.ts +212 -0
  87. package/dist/core/event.js +42 -0
  88. package/dist/core/event.js.map +1 -0
  89. package/dist/core/fhe-type.d.ts +75 -0
  90. package/dist/core/fhe-type.js +115 -0
  91. package/dist/core/fhe-type.js.map +1 -0
  92. package/dist/core/fhe.d.ts +11 -0
  93. package/dist/core/fhe.js +23 -0
  94. package/dist/core/fhe.js.map +1 -0
  95. package/dist/core/handle.d.ts +42 -0
  96. package/dist/core/handle.js +99 -0
  97. package/dist/core/handle.js.map +1 -0
  98. package/dist/core/json-utils.d.ts +18 -0
  99. package/dist/core/json-utils.js +37 -0
  100. package/dist/core/json-utils.js.map +1 -0
  101. package/dist/core/kms.d.ts +42 -0
  102. package/dist/core/kms.js +70 -0
  103. package/dist/core/kms.js.map +1 -0
  104. package/dist/core/logger.d.ts +3 -0
  105. package/dist/core/logger.js +11 -0
  106. package/dist/core/logger.js.map +1 -0
  107. package/dist/core/pretty-print.d.ts +18 -0
  108. package/dist/core/pretty-print.js +84 -0
  109. package/dist/core/pretty-print.js.map +1 -0
  110. package/dist/core/primitives.d.ts +22 -0
  111. package/dist/core/primitives.js +2 -0
  112. package/dist/core/primitives.js.map +1 -0
  113. package/dist/core/retryable-handler.d.ts +74 -0
  114. package/dist/core/retryable-handler.js +227 -0
  115. package/dist/core/retryable-handler.js.map +1 -0
  116. package/dist/core/signer-address-info.d.ts +15 -0
  117. package/dist/core/signer-address-info.js +33 -0
  118. package/dist/core/signer-address-info.js.map +1 -0
  119. package/dist/core/string.d.ts +28 -0
  120. package/dist/core/string.js +33 -0
  121. package/dist/core/string.js.map +1 -0
  122. package/dist/core/swallow.d.ts +23 -0
  123. package/dist/core/swallow.js +37 -0
  124. package/dist/core/swallow.js.map +1 -0
  125. package/dist/core/system-contract-info.d.ts +17 -0
  126. package/dist/core/system-contract-info.js +41 -0
  127. package/dist/core/system-contract-info.js.map +1 -0
  128. package/dist/core/ttl-cache.d.ts +81 -0
  129. package/dist/core/ttl-cache.js +113 -0
  130. package/dist/core/ttl-cache.js.map +1 -0
  131. package/dist/core/tx-error-parser.d.ts +40 -0
  132. package/dist/core/tx-error-parser.js +83 -0
  133. package/dist/core/tx-error-parser.js.map +1 -0
  134. package/dist/core/utils.d.ts +62 -0
  135. package/dist/core/utils.js +143 -0
  136. package/dist/core/utils.js.map +1 -0
  137. package/dist/index.d.ts +40 -0
  138. package/dist/index.js +48 -0
  139. package/dist/index.js.map +1 -0
  140. package/dist/jazz/encrypt-key-p.d.ts +65 -0
  141. package/dist/jazz/encrypt-key-p.js +283 -0
  142. package/dist/jazz/encrypt-key-p.js.map +1 -0
  143. package/dist/jazz/encrypt-p.d.ts +82 -0
  144. package/dist/jazz/encrypt-p.js +139 -0
  145. package/dist/jazz/encrypt-p.js.map +1 -0
  146. package/dist/jazz/encrypt.d.ts +58 -0
  147. package/dist/jazz/encrypt.js +155 -0
  148. package/dist/jazz/encrypt.js.map +1 -0
  149. package/dist/jazz/input-proof-p.d.ts +122 -0
  150. package/dist/jazz/input-proof-p.js +265 -0
  151. package/dist/jazz/input-proof-p.js.map +1 -0
  152. package/dist/jazz/jazz-client-i.d.ts +16 -0
  153. package/dist/jazz/jazz-client-i.js +2 -0
  154. package/dist/jazz/jazz-client-i.js.map +1 -0
  155. package/dist/jazz/jazz-client.d.ts +18 -0
  156. package/dist/jazz/jazz-client.js +24 -0
  157. package/dist/jazz/jazz-client.js.map +1 -0
  158. package/dist/jazz/key-pair.d.ts +50 -0
  159. package/dist/jazz/key-pair.js +166 -0
  160. package/dist/jazz/key-pair.js.map +1 -0
  161. package/dist/jazz/mock/fake.d.ts +3 -0
  162. package/dist/jazz/mock/fake.js +23 -0
  163. package/dist/jazz/mock/fake.js.map +1 -0
  164. package/dist/jazz/mock/fetch-input-proof.d.ts +4 -0
  165. package/dist/jazz/mock/fetch-input-proof.js +63 -0
  166. package/dist/jazz/mock/fetch-input-proof.js.map +1 -0
  167. package/dist/jazz/mock/fetch-key-url.d.ts +3 -0
  168. package/dist/jazz/mock/fetch-key-url.js +15 -0
  169. package/dist/jazz/mock/fetch-key-url.js.map +1 -0
  170. package/dist/jazz/mock/fetch-public-decrypt.d.ts +3 -0
  171. package/dist/jazz/mock/fetch-public-decrypt.js +81 -0
  172. package/dist/jazz/mock/fetch-public-decrypt.js.map +1 -0
  173. package/dist/jazz/mock/fetch-user-decrypt.d.ts +4 -0
  174. package/dist/jazz/mock/fetch-user-decrypt.js +174 -0
  175. package/dist/jazz/mock/fetch-user-decrypt.js.map +1 -0
  176. package/dist/jazz/module/fetch-input-proof.d.ts +19 -0
  177. package/dist/jazz/module/fetch-input-proof.js +72 -0
  178. package/dist/jazz/module/fetch-input-proof.js.map +1 -0
  179. package/dist/jazz/module/fetch-key-url.d.ts +17 -0
  180. package/dist/jazz/module/fetch-key-url.js +46 -0
  181. package/dist/jazz/module/fetch-key-url.js.map +1 -0
  182. package/dist/jazz/module/fetch-public-decrypt.d.ts +19 -0
  183. package/dist/jazz/module/fetch-public-decrypt.js +65 -0
  184. package/dist/jazz/module/fetch-public-decrypt.js.map +1 -0
  185. package/dist/jazz/module/fetch-user-decrypt.d.ts +19 -0
  186. package/dist/jazz/module/fetch-user-decrypt.js +109 -0
  187. package/dist/jazz/module/fetch-user-decrypt.js.map +1 -0
  188. package/dist/jazz/module/jazz-async-request.d.ts +102 -0
  189. package/dist/jazz/module/jazz-async-request.js +515 -0
  190. package/dist/jazz/module/jazz-async-request.js.map +1 -0
  191. package/dist/jazz/module/jazz-p.d.ts +61 -0
  192. package/dist/jazz/module/jazz-p.js +33 -0
  193. package/dist/jazz/module/jazz-p.js.map +1 -0
  194. package/dist/jazz/module/s3-download.d.ts +85 -0
  195. package/dist/jazz/module/s3-download.js +293 -0
  196. package/dist/jazz/module/s3-download.js.map +1 -0
  197. package/dist/jazz/permit.d.ts +200 -0
  198. package/dist/jazz/permit.js +319 -0
  199. package/dist/jazz/permit.js.map +1 -0
  200. package/dist/jazz/public-decrypt-p.d.ts +96 -0
  201. package/dist/jazz/public-decrypt-p.js +258 -0
  202. package/dist/jazz/public-decrypt-p.js.map +1 -0
  203. package/dist/jazz/public-decrypt.d.ts +48 -0
  204. package/dist/jazz/public-decrypt.js +156 -0
  205. package/dist/jazz/public-decrypt.js.map +1 -0
  206. package/dist/jazz/read-contract.d.ts +81 -0
  207. package/dist/jazz/read-contract.js +125 -0
  208. package/dist/jazz/read-contract.js.map +1 -0
  209. package/dist/jazz/types/common.d.ts +17 -0
  210. package/dist/jazz/types/common.js +2 -0
  211. package/dist/jazz/types/common.js.map +1 -0
  212. package/dist/jazz/types/input-proof.d.ts +76 -0
  213. package/dist/jazz/types/input-proof.js +2 -0
  214. package/dist/jazz/types/input-proof.js.map +1 -0
  215. package/dist/jazz/types/key-url.d.ts +68 -0
  216. package/dist/jazz/types/key-url.js +5 -0
  217. package/dist/jazz/types/key-url.js.map +1 -0
  218. package/dist/jazz/types/public-decrypt.d.ts +61 -0
  219. package/dist/jazz/types/public-decrypt.js +2 -0
  220. package/dist/jazz/types/public-decrypt.js.map +1 -0
  221. package/dist/jazz/types/user-decrypt.d.ts +123 -0
  222. package/dist/jazz/types/user-decrypt.js +2 -0
  223. package/dist/jazz/types/user-decrypt.js.map +1 -0
  224. package/dist/jazz/user-decrypt-p.d.ts +111 -0
  225. package/dist/jazz/user-decrypt-p.js +280 -0
  226. package/dist/jazz/user-decrypt-p.js.map +1 -0
  227. package/dist/jazz/user-decrypt.d.ts +74 -0
  228. package/dist/jazz/user-decrypt.js +143 -0
  229. package/dist/jazz/user-decrypt.js.map +1 -0
  230. package/dist/native/fhe-api.js +5959 -0
  231. package/dist/native/fhe-api.node.cjs +6167 -0
  232. package/dist/native/fhe-api.node.worker.cjs +210 -0
  233. package/dist/native/fhe-api.wasm +0 -0
  234. package/dist/native/fhe-api.worker.js +164 -0
  235. package/dist/native/kms/node/kms_lib.d.ts +38 -0
  236. package/dist/native/kms/node/kms_lib.js +356 -0
  237. package/dist/native/kms/node/kms_lib_bg.wasm +0 -0
  238. package/dist/native/kms/node/kms_lib_bg.wasm.d.ts +21 -0
  239. package/dist/native/kms/node/package.json +11 -0
  240. package/dist/native/kms/web/kms_lib.d.ts +84 -0
  241. package/dist/native/kms/web/kms_lib.js +443 -0
  242. package/dist/native/kms/web/kms_lib_bg.wasm +0 -0
  243. package/dist/native/kms/web/kms_lib_bg.wasm.d.ts +21 -0
  244. package/dist/native/kms/web/package.json +15 -0
  245. package/dist/runtime/browser.d.ts +36 -0
  246. package/dist/runtime/browser.js +115 -0
  247. package/dist/runtime/browser.js.map +1 -0
  248. package/dist/runtime/node.d.ts +30 -0
  249. package/dist/runtime/node.js +95 -0
  250. package/dist/runtime/node.js.map +1 -0
  251. package/dist/sdk/fhetransform-sdk-b.d.ts +102 -0
  252. package/dist/sdk/fhetransform-sdk-b.js +294 -0
  253. package/dist/sdk/fhetransform-sdk-b.js.map +1 -0
  254. package/dist/sdk/fhetransform-sdk.d.ts +87 -0
  255. package/dist/sdk/fhetransform-sdk.js +135 -0
  256. package/dist/sdk/fhetransform-sdk.js.map +1 -0
  257. package/dist/sdk/jazz-service.d.ts +13 -0
  258. package/dist/sdk/jazz-service.js +58 -0
  259. package/dist/sdk/jazz-service.js.map +1 -0
  260. package/dist/sdk/permit-service.d.ts +45 -0
  261. package/dist/sdk/permit-service.js +144 -0
  262. package/dist/sdk/permit-service.js.map +1 -0
  263. package/dist/wasm/fhe-wasm-client.d.ts +19 -0
  264. package/dist/wasm/fhe-wasm-client.js +23 -0
  265. package/dist/wasm/fhe-wasm-client.js.map +1 -0
  266. package/dist/wasm/fhe-wasm-module.d.ts +24 -0
  267. package/dist/wasm/fhe-wasm-module.js +141 -0
  268. package/dist/wasm/fhe-wasm-module.js.map +1 -0
  269. package/dist/wasm/fhe-wasm-type.d.ts +59 -0
  270. package/dist/wasm/fhe-wasm-type.js +244 -0
  271. package/dist/wasm/fhe-wasm-type.js.map +1 -0
  272. package/dist/wasm/wasm-loader.browser.d.ts +21 -0
  273. package/dist/wasm/wasm-loader.browser.js +143 -0
  274. package/dist/wasm/wasm-loader.browser.js.map +1 -0
  275. package/dist/wasm/wasm-loader.node.d.ts +24 -0
  276. package/dist/wasm/wasm-loader.node.js +114 -0
  277. package/dist/wasm/wasm-loader.node.js.map +1 -0
  278. package/dist/wasm/worker-client.browser.d.ts +6 -0
  279. package/dist/wasm/worker-client.browser.js +21 -0
  280. package/dist/wasm/worker-client.browser.js.map +1 -0
  281. package/dist/wasm/worker-client.d.ts +34 -0
  282. package/dist/wasm/worker-client.js +160 -0
  283. package/dist/wasm/worker-client.js.map +1 -0
  284. package/dist/wasm/worker-client.node.d.ts +6 -0
  285. package/dist/wasm/worker-client.node.js +20 -0
  286. package/dist/wasm/worker-client.node.js.map +1 -0
  287. package/dist/wasm/worker-message.d.ts +61 -0
  288. package/dist/wasm/worker-message.js +2 -0
  289. package/dist/wasm/worker-message.js.map +1 -0
  290. package/dist/wasm/worker-transport.browser.d.ts +15 -0
  291. package/dist/wasm/worker-transport.browser.js +35 -0
  292. package/dist/wasm/worker-transport.browser.js.map +1 -0
  293. package/dist/wasm/worker-transport.d.ts +6 -0
  294. package/dist/wasm/worker-transport.js +2 -0
  295. package/dist/wasm/worker-transport.js.map +1 -0
  296. package/dist/wasm/worker-transport.node.d.ts +17 -0
  297. package/dist/wasm/worker-transport.node.js +39 -0
  298. package/dist/wasm/worker-transport.node.js.map +1 -0
  299. package/dist/wasm/worker.d.ts +1 -0
  300. package/dist/wasm/worker.js +69 -0
  301. package/dist/wasm/worker.js.map +1 -0
  302. package/package.json +81 -0
@@ -0,0 +1,258 @@
1
+ import { ethers } from "ethers";
2
+ import { logger } from "../core/logger.js";
3
+ import { formatValue } from "../core/pretty-print.js";
4
+ import { readKmsSignersInfo } from "./read-contract.js";
5
+ import { aclAbi } from "../abis/acl.abi.js";
6
+ import { FheErrorCode } from "../core/errors/error-codes.js";
7
+ import { FheError } from "../core/errors/fhe-error.js";
8
+ // ============================================================================
9
+ // EIP-712 Constants
10
+ // ============================================================================
11
+ /**
12
+ * EIP-712 type definitions for KMS public decryption.
13
+ *
14
+ * CRITICAL: Field order is authoritative — it determines the EIP-712 type hash.
15
+ * Changing the order will produce a different signature and break on-chain verification.
16
+ * Must match the Solidity struct definition exactly.
17
+ */
18
+ export const kmsPublicDecryptEip712Types = {
19
+ EIP712Domain: [
20
+ { name: 'name', type: 'string' },
21
+ { name: 'version', type: 'string' },
22
+ { name: 'chainId', type: 'uint256' },
23
+ { name: 'verifyingContract', type: 'address' },
24
+ ],
25
+ // CRITICAL: Field order is authoritative — it determines the EIP-712 type hash.
26
+ // Changing the order will produce a different signature and break on-chain verification.
27
+ // Must match the Solidity struct definition exactly.
28
+ PublicDecryptSignData: [
29
+ { name: 'ctHandles', type: 'bytes32[]' },
30
+ { name: 'decryptedResult', type: 'bytes' },
31
+ { name: 'extraData', type: 'bytes' },
32
+ ],
33
+ };
34
+ // ============================================================================
35
+ // Signature Verification
36
+ // ============================================================================
37
+ /**
38
+ * Verifies KMS public decryption EIP-712 signatures.
39
+ *
40
+ * This function:
41
+ * 1. Reconstructs the EIP-712 message from the result
42
+ * 2. Recovers the signer addresses from each signature
43
+ * 3. Verifies all recovered addresses are in the KMS signer set
44
+ * 4. Verifies the threshold is met
45
+ *
46
+ * @param client - The Jazz client instance
47
+ * @param params - Verification parameters (chainId, verifyingContract, handles)
48
+ * @param result - Public decryption result containing signatures and decrypted data
49
+ * @throws Error if verification fails (unknown signer, threshold not met, invalid signature)
50
+ */
51
+ export async function verifyPublicDecryptionSignatures(client, params, result) {
52
+ // Enter method
53
+ logger.debug(() => ['[verifyPublicDecryptionSignatures] Enter', formatValue({ params, result })]);
54
+ // ============================================================================
55
+ // Step 1: Build EIP-712 Domain and Message
56
+ // ============================================================================
57
+ const domain = {
58
+ name: 'Decryption',
59
+ version: '1',
60
+ chainId: params.chainId,
61
+ verifyingContract: params.verifyingContract,
62
+ };
63
+ const types = kmsPublicDecryptEip712Types;
64
+ const primaryType = 'PublicDecryptSignData';
65
+ const message = {
66
+ ctHandles: [...params.handles],
67
+ decryptedResult: result.orderedAbiEncodedClearValues,
68
+ extraData: result.extraData,
69
+ };
70
+ logger.debug(() => ['[verifyPublicDecryptionSignatures] EIP-712 built',
71
+ formatValue({ domain, types, primaryType, message })]);
72
+ // ============================================================================
73
+ // Step 2: Recover Signer Addresses
74
+ // ============================================================================
75
+ const primaryTypeFields = types[primaryType];
76
+ if (primaryTypeFields === undefined) {
77
+ logger.error('[verifyPublicDecryptionSignatures] Primary type not found', {
78
+ primaryType,
79
+ });
80
+ throw new FheError({ code: FheErrorCode.Internal, message: `Primary type "${primaryType}" not found in types` });
81
+ }
82
+ const typesToSign = {
83
+ [primaryType]: [...primaryTypeFields],
84
+ };
85
+ const signatures = result.kmsPublicDecryptEIP712Signatures;
86
+ logger.debug('[verifyPublicDecryptionSignatures] Recovering signer addresses', {
87
+ signatureCount: signatures.length,
88
+ });
89
+ const recoveredAddresses = await Promise.all(signatures.map(async (signature, index) => {
90
+ try {
91
+ const signerAddress = ethers.verifyTypedData(domain, typesToSign, message, signature);
92
+ logger.debug('[verifyPublicDecryptionSignatures] Signature recovered', {
93
+ index,
94
+ signature: signature.substring(0, 20) + '...',
95
+ signerAddress,
96
+ });
97
+ return signerAddress;
98
+ }
99
+ catch (error) {
100
+ logger.error('[verifyPublicDecryptionSignatures] Failed to recover signature', {
101
+ index,
102
+ error: error.message,
103
+ });
104
+ throw error;
105
+ }
106
+ }));
107
+ logger.debug('[verifyPublicDecryptionSignatures] Recovered addresses', {
108
+ addresses: recoveredAddresses,
109
+ });
110
+ // ============================================================================
111
+ // Step 3: Verify Against KMS Signer Set
112
+ // ============================================================================
113
+ const { kmsSigners, publicDecryptionThreshold } = await readKmsSignersInfo(client);
114
+ // Verify all recovered signers are in the KMS signer set
115
+ const isInclude = recoveredAddresses.every(item => kmsSigners.includes(item));
116
+ if (!isInclude) {
117
+ logger.error('[verifyPublicDecryptionSignatures] Unknown KMS signer detected', {
118
+ recoveredAddresses,
119
+ allowedSigners: kmsSigners,
120
+ });
121
+ throw new FheError({ code: FheErrorCode.UnknownSigner, message: 'Unknown KMS Signer' });
122
+ }
123
+ // Verify threshold is met
124
+ if (recoveredAddresses.length < publicDecryptionThreshold) {
125
+ logger.error('[verifyPublicDecryptionSignatures] Threshold not met', {
126
+ recoveredCount: recoveredAddresses.length,
127
+ threshold: publicDecryptionThreshold,
128
+ });
129
+ throw new FheError({ code: FheErrorCode.ThresholdNotMet, message: 'recovered signer addresses should >= threshold' });
130
+ }
131
+ logger.debug('[verifyPublicDecryptionSignatures] All signatures verified successfully', {
132
+ recoveredCount: recoveredAddresses.length,
133
+ threshold: publicDecryptionThreshold,
134
+ });
135
+ }
136
+ // ============================================================================
137
+ // Proof Encoding
138
+ // ============================================================================
139
+ /**
140
+ * Creates a public decryption proof by encoding signatures and extra data.
141
+ *
142
+ * Format:
143
+ * Byte 0 : numSigners (uint8)
144
+ * Bytes 1 .. 65*N : N × 65-byte ECDSA signatures
145
+ * Bytes 65*N+1 .. end: extraData
146
+ *
147
+ * @param signatures - Array of signatures (hex strings with 0x prefix)
148
+ * @param extraData - Additional contextual data as Uint8Array
149
+ * @returns Encoded proof as Uint8Array
150
+ * @throws Error if numSigners exceeds 255 or signature length is invalid
151
+ */
152
+ export function createPublicDecryptionProof(signatures, extraData) {
153
+ // Enter method
154
+ logger.debug('[createPublicDecryptionProof] Enter', {
155
+ signatures, extraData,
156
+ });
157
+ const numSigners = signatures.length;
158
+ // ============================================================================
159
+ // Step 1: Validate Inputs
160
+ // ============================================================================
161
+ // Validate numSigners fits in 1 byte (max 255)
162
+ if (numSigners > 255) {
163
+ logger.error('[createPublicDecryptionProof] Signer count exceeds 255', {
164
+ numSigners,
165
+ });
166
+ throw new FheError({ code: FheErrorCode.InvalidArgument, message: `numSigners:${numSigners} must fit in 1 byte` });
167
+ }
168
+ // Validate and convert signatures to bytes
169
+ logger.trace('[createPublicDecryptionProof] Validating signatures');
170
+ const sigBytes = signatures.map((s, i) => {
171
+ const b = ethers.getBytes(s);
172
+ if (b.length !== 65) {
173
+ logger.error('[createPublicDecryptionProof] Invalid signature length', {
174
+ index: i,
175
+ signature: s.substring(0, 20) + '...',
176
+ expected: 65,
177
+ actual: b.length,
178
+ });
179
+ throw new FheError({ code: FheErrorCode.InvalidArgument, message: `the length of signature ${i} != 65 bytes` });
180
+ }
181
+ return b;
182
+ });
183
+ // ============================================================================
184
+ // Step 2: Build Encoded Proof
185
+ // ============================================================================
186
+ // Calculate total length: header(1) + signatures(65*n) + extraData
187
+ const totalLen = 1 + 65 * numSigners + extraData.length;
188
+ const proof = new Uint8Array(totalLen);
189
+ let offset = 0;
190
+ logger.trace('[createPublicDecryptionProof] Encoding proof data', {
191
+ totalLength: totalLen,
192
+ headerSize: 1,
193
+ signaturesSize: 65 * numSigners,
194
+ extraDataSize: extraData.length,
195
+ });
196
+ // Header: numSigners (1 byte)
197
+ proof[offset++] = numSigners;
198
+ // Signatures (65 bytes each)
199
+ for (let i = 0; i < sigBytes.length; i++) {
200
+ const b = sigBytes[i];
201
+ proof.set(b, offset);
202
+ offset += 65;
203
+ logger.trace('[createPublicDecryptionProof] Encoded signature', {
204
+ index: i,
205
+ offset: offset - 65,
206
+ size: b.length,
207
+ });
208
+ }
209
+ // Extra data (variable length)
210
+ if (extraData.length > 0) {
211
+ proof.set(extraData, offset);
212
+ offset += extraData.length;
213
+ logger.trace('[createPublicDecryptionProof] Encoded extra data', {
214
+ size: extraData.length,
215
+ offset: offset - extraData.length,
216
+ });
217
+ }
218
+ // Verify encoding offset matches total length
219
+ if (offset !== totalLen) {
220
+ logger.error('[createPublicDecryptionProof] Length mismatch', {
221
+ offset,
222
+ totalLen,
223
+ diff: offset - totalLen,
224
+ });
225
+ throw new FheError({ code: FheErrorCode.Internal, message: `proof encoding length mismatch: offset(${offset}) !== totalLen(${totalLen})` });
226
+ }
227
+ logger.debug('[createPublicDecryptionProof] Proof encoded successfully', {
228
+ totalBytes: totalLen,
229
+ numSigners,
230
+ extraDataSize: extraData.length,
231
+ });
232
+ return proof;
233
+ }
234
+ export async function checkPublicDecryptPermission(client, params) {
235
+ const { aclContractAddress, ctHandles } = params;
236
+ const provider = await client.sdk.requireProvider();
237
+ const contract = new ethers.Contract(aclContractAddress, aclAbi, provider);
238
+ // Check permissions for each handle
239
+ for (let i = 0; i < ctHandles.length; i++) {
240
+ const ctHandle = ctHandles[i];
241
+ logger.trace('[checkPublicDecryptPermission] Checking ACL permission', {
242
+ index: i,
243
+ handle: ctHandle,
244
+ });
245
+ const isAllowed = await contract.isAllowedForDecryption(ctHandle);
246
+ if (!isAllowed) {
247
+ logger.error('[checkPublicDecryptPermission] ACL permission denied', {
248
+ index: i,
249
+ handle: ctHandle,
250
+ });
251
+ throw new FheError({ code: FheErrorCode.PermissionDenied, message: `PublicDecryption: not allowed ${ctHandle}`, context: { handle: ctHandle } });
252
+ }
253
+ }
254
+ logger.debug('[checkPublicDecryptPermission] ACL permissions verified', {
255
+ allowedCount: ctHandles.length,
256
+ });
257
+ }
258
+ //# sourceMappingURL=public-decrypt-p.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-decrypt-p.js","sourceRoot":"","sources":["../../src/jazz/public-decrypt-p.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { HandleLike, Plaintext } from "../core/fhe-type.js";
2
+ import { BytesHex } from "../core/primitives.js";
3
+ import type { IJazzClient } from "./jazz-client-i.js";
4
+ import { JazzProcessOptions } from "./types/common.js";
5
+ /**
6
+ * Configuration options for public decryption operations.
7
+ */
8
+ export type PublicDecryptOptions = JazzProcessOptions & {
9
+ checkPermissions?: boolean;
10
+ };
11
+ /**
12
+ * Payload can be a single handle or an array of handles.
13
+ */
14
+ export type PublicDecryptPayload = HandleLike | HandleLike[];
15
+ /**
16
+ * Parameters for public decryption operations.
17
+ */
18
+ export type PublicDecryptParameters<T extends PublicDecryptPayload> = {
19
+ /** Handle(s) to decrypt */
20
+ readonly payloads: T;
21
+ /** Additional options */
22
+ readonly options?: PublicDecryptOptions;
23
+ };
24
+ /**
25
+ * Result of a public decryption operation.
26
+ */
27
+ export type PublicDecryptResult<T extends PublicDecryptPayload> = {
28
+ /** Decrypted plaintexts (single item or array matching input) */
29
+ readonly plaintexts: T extends HandleLike[] ? Plaintext[] : Plaintext;
30
+ /** Decryption proof as hex with 0x prefix */
31
+ readonly decryptionProof: BytesHex;
32
+ };
33
+ /**
34
+ * Decrypts a value or batch of values using public decryption.
35
+ *
36
+ * This function handles the complete public decryption flow:
37
+ * 1. Validates ACL permissions for each handle
38
+ * 2. Calls Jazz service for decryption
39
+ * 3. Verifies KMS signatures
40
+ * 4. Creates decryption proof
41
+ * 5. Decodes the clear values
42
+ *
43
+ * @param client - The Jazz client instance
44
+ * @param parameters - Public decryption parameters
45
+ * @returns PublicDecryptResult containing plaintexts and decryption proof
46
+ * @throws Error if ACL check fails, decryption fails, or signature verification fails
47
+ */
48
+ export declare function decryptPublicValue<T extends PublicDecryptPayload>(client: IJazzClient, parameters: PublicDecryptParameters<T>): Promise<PublicDecryptResult<T>>;
@@ -0,0 +1,156 @@
1
+ import { fetchPublicDecrypt } from "./module/fetch-public-decrypt.js";
2
+ import { fetchPublicDecrypt as fetchPublicDecryptMock } from "./mock/fetch-public-decrypt.js";
3
+ import { ethers } from "ethers";
4
+ import { bytesToHex, fromHexString } from "../core/bytes.js";
5
+ import { getHandleAbiType, getHandleFheType } from "../core/handle.js";
6
+ import { checkPublicDecryptPermission, createPublicDecryptionProof, verifyPublicDecryptionSignatures } from "./public-decrypt-p.js";
7
+ import { logger } from "../core/logger.js";
8
+ import { FheErrorCode } from "../core/errors/error-codes.js";
9
+ import { FheError } from "../core/errors/fhe-error.js";
10
+ import { formatValue } from "../core/pretty-print.js";
11
+ import { FheTransformSDKEvents } from "../core/event.js";
12
+ // ============================================================================
13
+ // Main Public Decryption Function
14
+ // ============================================================================
15
+ /**
16
+ * Decrypts a value or batch of values using public decryption.
17
+ *
18
+ * This function handles the complete public decryption flow:
19
+ * 1. Validates ACL permissions for each handle
20
+ * 2. Calls Jazz service for decryption
21
+ * 3. Verifies KMS signatures
22
+ * 4. Creates decryption proof
23
+ * 5. Decodes the clear values
24
+ *
25
+ * @param client - The Jazz client instance
26
+ * @param parameters - Public decryption parameters
27
+ * @returns PublicDecryptResult containing plaintexts and decryption proof
28
+ * @throws Error if ACL check fails, decryption fails, or signature verification fails
29
+ */
30
+ export async function decryptPublicValue(client, parameters) {
31
+ let t0;
32
+ // Enter method
33
+ logger.debug(() => ['[decryptPublicValue] Enter', formatValue({ parameters })]);
34
+ const isArray = Array.isArray(parameters.payloads);
35
+ const ctHandles = (isArray ? parameters.payloads : [parameters.payloads]);
36
+ const isMock = client.sdk.isMock();
37
+ const chainId = await client.sdk.getChainID();
38
+ const sysContractInfo = await client.sdk.getSystemContractInfo();
39
+ // ============================================================================
40
+ // Step 0: Input Validation
41
+ // ============================================================================
42
+ // TODO: Add input validation here
43
+ // - Validate ctHandles are not empty
44
+ // - Validate each handle is valid
45
+ // ============================================================================
46
+ // Step 1: Check ACL Permissions
47
+ // ============================================================================
48
+ if (parameters.options?.checkPermissions === true) {
49
+ logger.debug('[decryptPublicValue] Step 1: Checking ACL permissions');
50
+ t0 = Date.now();
51
+ await checkPublicDecryptPermission(client, {
52
+ aclContractAddress: sysContractInfo.aclContractAddress,
53
+ ctHandles: [...ctHandles],
54
+ });
55
+ client.sdk.emitEvent({ type: FheTransformSDKEvents.PublicDecryptionPermissionCheckEnd, durationMs: Date.now() - t0 });
56
+ }
57
+ // ============================================================================
58
+ // Step 2: Call Jazz for Decryption
59
+ // ============================================================================
60
+ logger.debug('[decryptPublicValue] Step 2: Fetching public decryption from Jazz');
61
+ const fetchPublicDecryptParameters = {
62
+ payload: {
63
+ orderedHandles: ctHandles,
64
+ extraData: "0x00",
65
+ },
66
+ options: { ...parameters.options },
67
+ };
68
+ let result;
69
+ client.sdk.emitEvent({ type: FheTransformSDKEvents.FetchPublicDecryptStart });
70
+ t0 = Date.now();
71
+ if (isMock) {
72
+ logger.trace('[decryptPublicValue] Using mock mode for public decryption');
73
+ result = await fetchPublicDecryptMock(client, fetchPublicDecryptParameters);
74
+ }
75
+ else {
76
+ logger.trace('[decryptPublicValue] Using production mode for public decryption');
77
+ result = await fetchPublicDecrypt(client, fetchPublicDecryptParameters);
78
+ }
79
+ client.sdk.emitEvent({ type: FheTransformSDKEvents.FetchPublicDecryptEnd, durationMs: Date.now() - t0 });
80
+ logger.debug('[decryptPublicValue] Public decryption fetched', {
81
+ decryptedValueLength: result.orderedAbiEncodedClearValues.length,
82
+ signaturesCount: result.kmsPublicDecryptEIP712Signatures.length,
83
+ extraData: result.extraData,
84
+ });
85
+ // ============================================================================
86
+ // Step 3: Verify KMS Signatures
87
+ // ============================================================================
88
+ t0 = Date.now();
89
+ logger.debug('[decryptPublicValue] Step 3: Verifying KMS signatures');
90
+ await verifyPublicDecryptionSignatures(client, {
91
+ chainId: chainId,
92
+ verifyingContract: sysContractInfo.decryptionContractAddress,
93
+ handles: [...ctHandles],
94
+ }, result);
95
+ logger.debug('[decryptPublicValue] KMS signatures verified successfully');
96
+ client.sdk.emitEvent({ type: FheTransformSDKEvents.VerifyPublicDecryptionSignaturesEnd, durationMs: Date.now() - t0 });
97
+ // ============================================================================
98
+ // Step 4: Create Decryption Proof
99
+ // ============================================================================
100
+ logger.debug('[decryptPublicValue] Step 4: Creating decryption proof');
101
+ const decryptionProofBytes = createPublicDecryptionProof([...result.kmsPublicDecryptEIP712Signatures], fromHexString(result.extraData));
102
+ const decryptionProof = bytesToHex(decryptionProofBytes);
103
+ logger.trace('[decryptPublicValue] Decryption proof created', {
104
+ proofSize: decryptionProofBytes.length,
105
+ proofHexLength: decryptionProof.length,
106
+ });
107
+ // ============================================================================
108
+ // Step 5: Decode Clear Values
109
+ // ============================================================================
110
+ logger.debug('[decryptPublicValue] Step 5: Decoding clear values');
111
+ // Build ABI types for each handle
112
+ const abiTypes = ctHandles.map(h => getHandleAbiType(h));
113
+ logger.trace('[decryptPublicValue] ABI types', {
114
+ types: abiTypes,
115
+ });
116
+ // Decode the concatenated ABI-encoded values
117
+ const abiCoder = ethers.AbiCoder.defaultAbiCoder();
118
+ const decoded = abiCoder.decode(abiTypes, result.orderedAbiEncodedClearValues);
119
+ if (decoded.length !== ctHandles.length) {
120
+ throw new FheError({
121
+ code: FheErrorCode.DecryptionFailed,
122
+ message: `Decoded value count (${decoded.length}) does not match handles (${ctHandles.length})`,
123
+ });
124
+ }
125
+ logger.debug('[decryptPublicValue] Values decoded', {
126
+ decodedCount: decoded.length,
127
+ decodedValues: decoded.map((v) => v.toString()),
128
+ });
129
+ // Build plaintext results
130
+ const results = [];
131
+ for (let i = 0; i < ctHandles.length; i++) {
132
+ const plaintext = {
133
+ type: getHandleFheType(ctHandles[i]),
134
+ value: decoded[i],
135
+ };
136
+ results.push(plaintext);
137
+ logger.trace('[decryptPublicValue] Plaintext constructed', {
138
+ index: i,
139
+ type: plaintext.type,
140
+ value: plaintext.value.toString(),
141
+ });
142
+ }
143
+ // ============================================================================
144
+ // Step 6: Return Result
145
+ // ============================================================================
146
+ logger.info('[decryptPublicValue] Public decryption completed successfully', {
147
+ resultCount: results.length,
148
+ isArray,
149
+ proofSize: decryptionProof.length,
150
+ });
151
+ return {
152
+ plaintexts: isArray ? results : results[0],
153
+ decryptionProof: decryptionProof,
154
+ };
155
+ }
156
+ //# sourceMappingURL=public-decrypt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-decrypt.js","sourceRoot":"","sources":["../../src/jazz/public-decrypt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import type { IJazzClient } from "./jazz-client-i.js";
2
+ /**
3
+ * Type definition for Alphatrion signers information retrieved from the contract.
4
+ */
5
+ export type ReadAlphatrionSignersInfo = {
6
+ /** Array of Alphatrion signer addresses */
7
+ alphatrionSigners: string[];
8
+ /** Threshold number of signatures required for Alphatrion operations */
9
+ alphatrionThreshold: number;
10
+ };
11
+ /**
12
+ * Retrieves Alphatrion signers and threshold from the SpaceBridge configuration contract.
13
+ * Results are cached to minimize expensive blockchain RPC calls.
14
+ *
15
+ * @param client - The Jazz client instance providing SDK and provider access
16
+ * @param forceRefresh - If true, bypasses cache and fetches fresh data from the contract
17
+ * @returns Promise containing Alphatrion signers array and threshold
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * // Get cached data (or fetch if expired)
22
+ * const info = await readAlphatrionSignersInfo(client);
23
+ *
24
+ * // Force fresh data from contract
25
+ * const freshInfo = await readAlphatrionSignersInfo(client, true);
26
+ * ```
27
+ */
28
+ export declare function readAlphatrionSignersInfo(client: IJazzClient, forceRefresh?: boolean): Promise<ReadAlphatrionSignersInfo>;
29
+ /**
30
+ * Type definition for KMS signers information retrieved from the contract.
31
+ */
32
+ export type ReadKmsSignersInfo = {
33
+ /** Array of KMS signer addresses */
34
+ kmsSigners: string[];
35
+ /** Threshold for public decryption operations */
36
+ publicDecryptionThreshold: number;
37
+ /** Threshold for user decryption operations */
38
+ userDecryptionThreshold: number;
39
+ };
40
+ /**
41
+ * Retrieves KMS signers and decryption thresholds from the SpaceBridge configuration contract.
42
+ * Results are cached to minimize expensive blockchain RPC calls.
43
+ *
44
+ * @param client - The Jazz client instance providing SDK and provider access
45
+ * @param forceRefresh - If true, bypasses cache and fetches fresh data from the contract
46
+ * @returns Promise containing KMS signers array and decryption thresholds
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * // Get cached data (or fetch if expired)
51
+ * const info = await readKmsSignersInfo(client);
52
+ *
53
+ * // Force fresh data from contract
54
+ * const freshInfo = await readKmsSignersInfo(client, true);
55
+ * ```
56
+ */
57
+ export declare function readKmsSignersInfo(client: IJazzClient, forceRefresh?: boolean): Promise<ReadKmsSignersInfo>;
58
+ /**
59
+ * Utility function to clear all cached contract information.
60
+ * Useful when the contract configuration is known to have changed.
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * // Clear all caches after a contract upgrade
65
+ * clearAllContractCaches();
66
+ * ```
67
+ */
68
+ export declare function clearAllContractCaches(): void;
69
+ /**
70
+ * Utility function to refresh all cached contract information simultaneously.
71
+ *
72
+ * @param client - The Jazz client instance
73
+ * @returns Promise that resolves when all data has been refreshed
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * // Force refresh all cached contract data
78
+ * await refreshAllContractCaches(client);
79
+ * ```
80
+ */
81
+ export declare function refreshAllContractCaches(client: IJazzClient): Promise<void>;