@unionlabs/payments 0.1.0 → 0.2.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 (393) hide show
  1. package/Abi/package.json +6 -0
  2. package/Attestor/package.json +6 -0
  3. package/Constants/package.json +6 -0
  4. package/Domain/package.json +6 -0
  5. package/Error/package.json +6 -0
  6. package/EvmPublicClient/package.json +6 -0
  7. package/EvmWalletClient/package.json +6 -0
  8. package/Payment/package.json +6 -0
  9. package/PaymentError/package.json +6 -0
  10. package/Prover/package.json +6 -0
  11. package/PublicClient/package.json +6 -0
  12. package/README.md +1 -0
  13. package/Schema/package.json +6 -0
  14. package/Utils/package.json +6 -0
  15. package/WalletClient/package.json +6 -0
  16. package/attestation/package.json +6 -0
  17. package/cli/commands/balance/package.json +6 -0
  18. package/cli/commands/deposit/package.json +6 -0
  19. package/cli/commands/export-verifier/package.json +6 -0
  20. package/cli/commands/generate/package.json +6 -0
  21. package/cli/commands/history/package.json +6 -0
  22. package/cli/commands/prove/package.json +6 -0
  23. package/cli/commands/redeem/package.json +6 -0
  24. package/cli/commands/update-client/package.json +6 -0
  25. package/cli/config/package.json +6 -0
  26. package/cli/package.json +6 -0
  27. package/cli/utils/package.json +6 -0
  28. package/constants/ibc-core-registry/package.json +6 -0
  29. package/constants/services/package.json +6 -0
  30. package/constants/z-asset-registry/package.json +6 -0
  31. package/dist/cjs/Abi.js +270 -0
  32. package/dist/cjs/Abi.js.map +1 -0
  33. package/dist/cjs/Attestor.js +76 -0
  34. package/dist/cjs/Attestor.js.map +1 -0
  35. package/dist/cjs/Constants.js +8 -0
  36. package/dist/cjs/Constants.js.map +1 -0
  37. package/dist/cjs/Domain.js +24 -0
  38. package/dist/cjs/Domain.js.map +1 -0
  39. package/dist/cjs/Error.js +100 -0
  40. package/dist/cjs/Error.js.map +1 -0
  41. package/dist/cjs/EvmPublicClient.js +301 -0
  42. package/dist/cjs/EvmPublicClient.js.map +1 -0
  43. package/dist/cjs/EvmWalletClient.js +670 -0
  44. package/dist/cjs/EvmWalletClient.js.map +1 -0
  45. package/dist/cjs/Payment.js +333 -0
  46. package/dist/cjs/Payment.js.map +1 -0
  47. package/dist/cjs/PaymentError.js +32 -0
  48. package/dist/cjs/PaymentError.js.map +1 -0
  49. package/dist/cjs/Prover.js +153 -0
  50. package/dist/cjs/Prover.js.map +1 -0
  51. package/dist/cjs/PublicClient.js +39 -0
  52. package/dist/cjs/PublicClient.js.map +1 -0
  53. package/dist/cjs/Schema.js +38 -0
  54. package/dist/cjs/Schema.js.map +1 -0
  55. package/dist/cjs/Utils.js +33 -0
  56. package/dist/cjs/Utils.js.map +1 -0
  57. package/dist/cjs/WalletClient.js +39 -0
  58. package/dist/cjs/WalletClient.js.map +1 -0
  59. package/dist/cjs/attestation.js +49 -0
  60. package/dist/cjs/attestation.js.map +1 -0
  61. package/dist/cjs/cli/commands/balance.js +60 -0
  62. package/dist/cjs/cli/commands/balance.js.map +1 -0
  63. package/dist/cjs/cli/commands/deposit.js +58 -0
  64. package/dist/cjs/cli/commands/deposit.js.map +1 -0
  65. package/dist/cjs/cli/commands/export-verifier.js +27 -0
  66. package/dist/cjs/cli/commands/export-verifier.js.map +1 -0
  67. package/dist/cjs/cli/commands/generate.js +41 -0
  68. package/dist/cjs/cli/commands/generate.js.map +1 -0
  69. package/dist/cjs/cli/commands/history.js +59 -0
  70. package/dist/cjs/cli/commands/history.js.map +1 -0
  71. package/dist/cjs/cli/commands/prove.js +82 -0
  72. package/dist/cjs/cli/commands/prove.js.map +1 -0
  73. package/dist/cjs/cli/commands/redeem.js +152 -0
  74. package/dist/cjs/cli/commands/redeem.js.map +1 -0
  75. package/dist/cjs/cli/commands/update-client.js +62 -0
  76. package/dist/cjs/cli/commands/update-client.js.map +1 -0
  77. package/dist/cjs/cli/config.js +32 -0
  78. package/dist/cjs/cli/config.js.map +1 -0
  79. package/dist/cjs/cli/utils.js +108 -0
  80. package/dist/cjs/cli/utils.js.map +1 -0
  81. package/dist/cjs/cli.js +24 -0
  82. package/dist/cjs/cli.js.map +1 -0
  83. package/dist/cjs/constants/ibc-core-registry.js +30 -0
  84. package/dist/cjs/constants/ibc-core-registry.js.map +1 -0
  85. package/dist/cjs/constants/services.js +9 -0
  86. package/dist/cjs/constants/services.js.map +1 -0
  87. package/dist/cjs/constants/z-asset-registry.js +32 -0
  88. package/dist/cjs/constants/z-asset-registry.js.map +1 -0
  89. package/dist/cjs/gen/prover_pb.js +81 -0
  90. package/dist/cjs/gen/prover_pb.js.map +1 -0
  91. package/dist/cjs/index.js +32 -0
  92. package/dist/cjs/index.js.map +1 -0
  93. package/dist/cjs/internal/evm.js +191 -0
  94. package/dist/cjs/internal/evm.js.map +1 -0
  95. package/dist/cjs/internal/evmWalletClient.js +6 -0
  96. package/dist/cjs/internal/evmWalletClient.js.map +1 -0
  97. package/dist/cjs/internal/publicClient.js +49 -0
  98. package/dist/cjs/internal/publicClient.js.map +1 -0
  99. package/dist/cjs/internal/walletClient.js +43 -0
  100. package/dist/cjs/internal/walletClient.js.map +1 -0
  101. package/dist/cjs/legacy/client.js +1222 -0
  102. package/dist/cjs/legacy/client.js.map +1 -0
  103. package/dist/cjs/legacy/prover.js +112 -0
  104. package/dist/cjs/legacy/prover.js.map +1 -0
  105. package/dist/cjs/poseidon2.js +226 -0
  106. package/dist/cjs/poseidon2.js.map +1 -0
  107. package/dist/cjs/promises/Attestor.js +23 -0
  108. package/dist/cjs/promises/Attestor.js.map +1 -0
  109. package/dist/cjs/promises/EvmPublicClient.js +34 -0
  110. package/dist/cjs/promises/EvmPublicClient.js.map +1 -0
  111. package/dist/cjs/promises/EvmWalletClient.js +51 -0
  112. package/dist/cjs/promises/EvmWalletClient.js.map +1 -0
  113. package/dist/cjs/promises/Payment.js +22 -0
  114. package/dist/cjs/promises/Payment.js.map +1 -0
  115. package/dist/cjs/promises/Prover.js +26 -0
  116. package/dist/cjs/promises/Prover.js.map +1 -0
  117. package/dist/cjs/promises/PublicClient.js +53 -0
  118. package/dist/cjs/promises/PublicClient.js.map +1 -0
  119. package/dist/cjs/promises/WalletClient.js +44 -0
  120. package/dist/cjs/promises/WalletClient.js.map +1 -0
  121. package/dist/cjs/promises/index.js +22 -0
  122. package/dist/cjs/promises/index.js.map +1 -0
  123. package/dist/cjs/rpc.js +867 -0
  124. package/dist/cjs/rpc.js.map +1 -0
  125. package/dist/cjs/types.js +6 -0
  126. package/dist/cjs/types.js.map +1 -0
  127. package/dist/dts/Abi.d.ts +220 -0
  128. package/dist/dts/Abi.d.ts.map +1 -0
  129. package/dist/dts/Attestor.d.ts +42 -0
  130. package/dist/dts/Attestor.d.ts.map +1 -0
  131. package/dist/dts/Constants.d.ts +3 -0
  132. package/dist/dts/Constants.d.ts.map +1 -0
  133. package/dist/dts/Domain.d.ts +141 -0
  134. package/dist/dts/Domain.d.ts.map +1 -0
  135. package/dist/dts/Error.d.ts +102 -0
  136. package/dist/dts/Error.d.ts.map +1 -0
  137. package/dist/dts/EvmPublicClient.d.ts +61 -0
  138. package/dist/dts/EvmPublicClient.d.ts.map +1 -0
  139. package/dist/dts/EvmWalletClient.d.ts +67 -0
  140. package/dist/dts/EvmWalletClient.d.ts.map +1 -0
  141. package/dist/dts/Payment.d.ts +128 -0
  142. package/dist/dts/Payment.d.ts.map +1 -0
  143. package/dist/dts/PaymentError.d.ts +21 -0
  144. package/dist/dts/PaymentError.d.ts.map +1 -0
  145. package/dist/dts/Prover.d.ts +87 -0
  146. package/dist/dts/Prover.d.ts.map +1 -0
  147. package/dist/dts/PublicClient.d.ts +146 -0
  148. package/dist/dts/PublicClient.d.ts.map +1 -0
  149. package/dist/dts/Schema.d.ts +16 -0
  150. package/dist/dts/Schema.d.ts.map +1 -0
  151. package/dist/dts/Utils.d.ts +11 -0
  152. package/dist/dts/Utils.d.ts.map +1 -0
  153. package/dist/dts/WalletClient.d.ts +123 -0
  154. package/dist/dts/WalletClient.d.ts.map +1 -0
  155. package/dist/dts/attestation.d.ts +13 -0
  156. package/dist/dts/attestation.d.ts.map +1 -0
  157. package/dist/dts/cli/commands/balance.d.ts +3 -0
  158. package/dist/dts/cli/commands/balance.d.ts.map +1 -0
  159. package/dist/dts/cli/commands/deposit.d.ts +3 -0
  160. package/dist/dts/cli/commands/deposit.d.ts.map +1 -0
  161. package/dist/dts/cli/commands/export-verifier.d.ts +3 -0
  162. package/dist/dts/cli/commands/export-verifier.d.ts.map +1 -0
  163. package/dist/dts/cli/commands/generate.d.ts +3 -0
  164. package/dist/dts/cli/commands/generate.d.ts.map +1 -0
  165. package/dist/dts/cli/commands/history.d.ts +3 -0
  166. package/dist/dts/cli/commands/history.d.ts.map +1 -0
  167. package/dist/dts/cli/commands/prove.d.ts +3 -0
  168. package/dist/dts/cli/commands/prove.d.ts.map +1 -0
  169. package/dist/dts/cli/commands/redeem.d.ts +3 -0
  170. package/dist/dts/cli/commands/redeem.d.ts.map +1 -0
  171. package/dist/dts/cli/commands/update-client.d.ts +3 -0
  172. package/dist/dts/cli/commands/update-client.d.ts.map +1 -0
  173. package/dist/dts/cli/config.d.ts +14 -0
  174. package/dist/dts/cli/config.d.ts.map +1 -0
  175. package/dist/dts/cli/utils.d.ts +11 -0
  176. package/dist/dts/cli/utils.d.ts.map +1 -0
  177. package/dist/dts/cli.d.ts +3 -0
  178. package/dist/dts/cli.d.ts.map +1 -0
  179. package/dist/dts/constants/ibc-core-registry.d.ts +11 -0
  180. package/dist/dts/constants/ibc-core-registry.d.ts.map +1 -0
  181. package/dist/dts/constants/services.d.ts +3 -0
  182. package/dist/dts/constants/services.d.ts.map +1 -0
  183. package/dist/dts/constants/z-asset-registry.d.ts +13 -0
  184. package/dist/dts/constants/z-asset-registry.d.ts.map +1 -0
  185. package/dist/dts/gen/prover_pb.d.ts +300 -0
  186. package/dist/dts/gen/prover_pb.d.ts.map +1 -0
  187. package/dist/dts/index.d.ts +21 -0
  188. package/dist/dts/index.d.ts.map +1 -0
  189. package/dist/dts/internal/evm.d.ts +250 -0
  190. package/dist/dts/internal/evm.d.ts.map +1 -0
  191. package/dist/dts/internal/evmWalletClient.d.ts +2 -0
  192. package/dist/dts/internal/evmWalletClient.d.ts.map +1 -0
  193. package/dist/dts/internal/publicClient.d.ts +2 -0
  194. package/dist/dts/internal/publicClient.d.ts.map +1 -0
  195. package/dist/dts/internal/walletClient.d.ts +2 -0
  196. package/dist/dts/internal/walletClient.d.ts.map +1 -0
  197. package/dist/dts/legacy/client.d.ts +313 -0
  198. package/dist/dts/legacy/client.d.ts.map +1 -0
  199. package/dist/dts/legacy/prover.d.ts +30 -0
  200. package/dist/dts/legacy/prover.d.ts.map +1 -0
  201. package/dist/dts/poseidon2.d.ts +18 -0
  202. package/dist/dts/poseidon2.d.ts.map +1 -0
  203. package/dist/dts/promises/Attestor.d.ts +17 -0
  204. package/dist/dts/promises/Attestor.d.ts.map +1 -0
  205. package/dist/dts/promises/EvmPublicClient.d.ts +3709 -0
  206. package/dist/dts/promises/EvmPublicClient.d.ts.map +1 -0
  207. package/dist/dts/promises/EvmWalletClient.d.ts +4502 -0
  208. package/dist/dts/promises/EvmWalletClient.d.ts.map +1 -0
  209. package/dist/dts/promises/Payment.d.ts +33 -0
  210. package/dist/dts/promises/Payment.d.ts.map +1 -0
  211. package/dist/dts/promises/Prover.d.ts +14 -0
  212. package/dist/dts/promises/Prover.d.ts.map +1 -0
  213. package/dist/dts/promises/PublicClient.d.ts +23 -0
  214. package/dist/dts/promises/PublicClient.d.ts.map +1 -0
  215. package/dist/dts/promises/WalletClient.d.ts +57 -0
  216. package/dist/dts/promises/WalletClient.d.ts.map +1 -0
  217. package/dist/dts/promises/index.d.ts +8 -0
  218. package/dist/dts/promises/index.d.ts.map +1 -0
  219. package/dist/dts/rpc.d.ts +148 -0
  220. package/dist/dts/rpc.d.ts.map +1 -0
  221. package/dist/dts/types.d.ts +263 -0
  222. package/dist/dts/types.d.ts.map +1 -0
  223. package/dist/esm/Abi.js +264 -0
  224. package/dist/esm/Abi.js.map +1 -0
  225. package/dist/esm/Attestor.js +68 -0
  226. package/dist/esm/Attestor.js.map +1 -0
  227. package/dist/esm/Constants.js +2 -0
  228. package/dist/esm/Constants.js.map +1 -0
  229. package/dist/esm/Domain.js +17 -0
  230. package/dist/esm/Domain.js.map +1 -0
  231. package/dist/esm/Error.js +89 -0
  232. package/dist/esm/Error.js.map +1 -0
  233. package/dist/esm/EvmPublicClient.js +292 -0
  234. package/dist/esm/EvmPublicClient.js.map +1 -0
  235. package/dist/esm/EvmWalletClient.js +659 -0
  236. package/dist/esm/EvmWalletClient.js.map +1 -0
  237. package/dist/esm/Payment.js +323 -0
  238. package/dist/esm/Payment.js.map +1 -0
  239. package/dist/esm/PaymentError.js +24 -0
  240. package/dist/esm/PaymentError.js.map +1 -0
  241. package/dist/esm/Prover.js +142 -0
  242. package/dist/esm/Prover.js.map +1 -0
  243. package/dist/esm/PublicClient.js +30 -0
  244. package/dist/esm/PublicClient.js.map +1 -0
  245. package/dist/esm/Schema.js +31 -0
  246. package/dist/esm/Schema.js.map +1 -0
  247. package/dist/esm/Utils.js +27 -0
  248. package/dist/esm/Utils.js.map +1 -0
  249. package/dist/esm/WalletClient.js +30 -0
  250. package/dist/esm/WalletClient.js.map +1 -0
  251. package/dist/esm/attestation.js +42 -0
  252. package/dist/esm/attestation.js.map +1 -0
  253. package/dist/esm/cli/commands/balance.js +54 -0
  254. package/dist/esm/cli/commands/balance.js.map +1 -0
  255. package/dist/esm/cli/commands/deposit.js +52 -0
  256. package/dist/esm/cli/commands/deposit.js.map +1 -0
  257. package/dist/esm/cli/commands/export-verifier.js +21 -0
  258. package/dist/esm/cli/commands/export-verifier.js.map +1 -0
  259. package/dist/esm/cli/commands/generate.js +35 -0
  260. package/dist/esm/cli/commands/generate.js.map +1 -0
  261. package/dist/esm/cli/commands/history.js +53 -0
  262. package/dist/esm/cli/commands/history.js.map +1 -0
  263. package/dist/esm/cli/commands/prove.js +76 -0
  264. package/dist/esm/cli/commands/prove.js.map +1 -0
  265. package/dist/esm/cli/commands/redeem.js +146 -0
  266. package/dist/esm/cli/commands/redeem.js.map +1 -0
  267. package/dist/esm/cli/commands/update-client.js +56 -0
  268. package/dist/esm/cli/commands/update-client.js.map +1 -0
  269. package/dist/esm/cli/config.js +26 -0
  270. package/dist/esm/cli/config.js.map +1 -0
  271. package/dist/esm/cli/utils.js +94 -0
  272. package/dist/esm/cli/utils.js.map +1 -0
  273. package/dist/esm/cli.js +22 -0
  274. package/dist/esm/cli.js.map +1 -0
  275. package/dist/esm/constants/ibc-core-registry.js +21 -0
  276. package/dist/esm/constants/ibc-core-registry.js.map +1 -0
  277. package/dist/esm/constants/services.js +3 -0
  278. package/dist/esm/constants/services.js.map +1 -0
  279. package/dist/esm/constants/z-asset-registry.js +23 -0
  280. package/dist/esm/constants/z-asset-registry.js.map +1 -0
  281. package/dist/esm/gen/prover_pb.js +74 -0
  282. package/dist/esm/gen/prover_pb.js.map +1 -0
  283. package/dist/esm/index.js +22 -0
  284. package/dist/esm/index.js.map +1 -0
  285. package/dist/esm/internal/evm.js +169 -0
  286. package/dist/esm/internal/evm.js.map +1 -0
  287. package/dist/esm/internal/evmWalletClient.js +2 -0
  288. package/dist/esm/internal/evmWalletClient.js.map +1 -0
  289. package/dist/esm/internal/publicClient.js +41 -0
  290. package/dist/esm/internal/publicClient.js.map +1 -0
  291. package/dist/esm/internal/walletClient.js +35 -0
  292. package/dist/esm/internal/walletClient.js.map +1 -0
  293. package/dist/esm/legacy/client.js +1212 -0
  294. package/dist/esm/legacy/client.js.map +1 -0
  295. package/dist/esm/legacy/prover.js +105 -0
  296. package/dist/esm/legacy/prover.js.map +1 -0
  297. package/dist/esm/package.json +4 -0
  298. package/dist/esm/poseidon2.js +218 -0
  299. package/dist/esm/poseidon2.js.map +1 -0
  300. package/dist/esm/promises/Attestor.js +14 -0
  301. package/dist/esm/promises/Attestor.js.map +1 -0
  302. package/dist/esm/promises/EvmPublicClient.js +26 -0
  303. package/dist/esm/promises/EvmPublicClient.js.map +1 -0
  304. package/dist/esm/promises/EvmWalletClient.js +43 -0
  305. package/dist/esm/promises/EvmWalletClient.js.map +1 -0
  306. package/dist/esm/promises/Payment.js +13 -0
  307. package/dist/esm/promises/Payment.js.map +1 -0
  308. package/dist/esm/promises/Prover.js +17 -0
  309. package/dist/esm/promises/Prover.js.map +1 -0
  310. package/dist/esm/promises/PublicClient.js +45 -0
  311. package/dist/esm/promises/PublicClient.js.map +1 -0
  312. package/dist/esm/promises/WalletClient.js +36 -0
  313. package/dist/esm/promises/WalletClient.js.map +1 -0
  314. package/dist/esm/promises/index.js +8 -0
  315. package/dist/esm/promises/index.js.map +1 -0
  316. package/dist/esm/rpc.js +850 -0
  317. package/dist/esm/rpc.js.map +1 -0
  318. package/dist/esm/types.js +2 -0
  319. package/dist/esm/types.js.map +1 -0
  320. package/gen/prover_pb/package.json +6 -0
  321. package/index/package.json +6 -0
  322. package/legacy/client/package.json +6 -0
  323. package/legacy/prover/package.json +6 -0
  324. package/package.json +397 -44
  325. package/poseidon2/package.json +6 -0
  326. package/promises/Attestor/package.json +6 -0
  327. package/promises/EvmPublicClient/package.json +6 -0
  328. package/promises/EvmWalletClient/package.json +6 -0
  329. package/promises/Payment/package.json +6 -0
  330. package/promises/Prover/package.json +6 -0
  331. package/promises/PublicClient/package.json +6 -0
  332. package/promises/WalletClient/package.json +6 -0
  333. package/promises/index/package.json +6 -0
  334. package/promises/package.json +6 -0
  335. package/rpc/package.json +6 -0
  336. package/src/Abi.ts +195 -0
  337. package/src/Attestor.ts +113 -0
  338. package/src/Constants.ts +4 -0
  339. package/src/Domain.ts +52 -0
  340. package/src/Error.ts +163 -0
  341. package/src/EvmPublicClient.ts +549 -0
  342. package/src/EvmWalletClient.ts +1034 -0
  343. package/src/Payment.ts +523 -0
  344. package/src/PaymentError.ts +39 -0
  345. package/src/Prover.ts +240 -0
  346. package/src/PublicClient.ts +196 -0
  347. package/src/Schema.ts +36 -0
  348. package/src/Utils.ts +43 -0
  349. package/src/WalletClient.ts +172 -0
  350. package/src/attestation.ts +69 -0
  351. package/src/cli/commands/balance.ts +88 -0
  352. package/src/cli/commands/deposit.ts +104 -0
  353. package/src/cli/commands/export-verifier.ts +28 -0
  354. package/src/cli/commands/generate.ts +86 -0
  355. package/src/cli/commands/history.ts +91 -0
  356. package/src/cli/commands/prove.ts +133 -0
  357. package/src/cli/commands/redeem.ts +277 -0
  358. package/src/cli/commands/update-client.ts +96 -0
  359. package/src/cli/config.ts +55 -0
  360. package/src/cli/utils.ts +136 -0
  361. package/src/cli.ts +31 -0
  362. package/src/constants/ibc-core-registry.ts +44 -0
  363. package/src/constants/services.ts +4 -0
  364. package/src/constants/z-asset-registry.ts +47 -0
  365. package/src/gen/prover_pb.ts +375 -0
  366. package/src/index.ts +23 -0
  367. package/src/internal/evm.ts +361 -0
  368. package/src/internal/evmWalletClient.ts +0 -0
  369. package/src/internal/publicClient.ts +57 -0
  370. package/src/internal/walletClient.ts +50 -0
  371. package/src/legacy/client.ts +1652 -0
  372. package/src/legacy/prover.ts +135 -0
  373. package/src/poseidon2.ts +246 -0
  374. package/src/promises/Attestor.ts +25 -0
  375. package/src/promises/EvmPublicClient.ts +39 -0
  376. package/src/promises/EvmWalletClient.ts +63 -0
  377. package/src/promises/Payment.ts +86 -0
  378. package/src/promises/Prover.ts +26 -0
  379. package/src/promises/PublicClient.ts +47 -0
  380. package/src/promises/WalletClient.ts +38 -0
  381. package/src/promises/index.ts +7 -0
  382. package/src/rpc.ts +994 -0
  383. package/src/types.ts +281 -0
  384. package/types/package.json +6 -0
  385. package/dist/LICENSE +0 -1
  386. package/dist/chunk-37PNLRA6.js +0 -2418
  387. package/dist/cli.cjs +0 -3031
  388. package/dist/cli.js +0 -675
  389. package/dist/index.cjs +0 -2451
  390. package/dist/index.js +0 -1
  391. package/dist/package.json +0 -18
  392. package/dist/payments.d.ts +0 -835
  393. /package/{dist → src}/tsdoc-metadata.json +0 -0
@@ -1,2418 +0,0 @@
1
- import * as V from 'viem';
2
- import { hexToBigInt as hexToBigInt$1, http, createPublicClient, toRlp, keccak256, encodeAbiParameters, hexToBytes, sha256, padHex, toHex, encodePacked, bytesToHex } from 'viem';
3
- import { sign } from 'viem/accounts';
4
- import { createClient } from '@connectrpc/connect';
5
- import { createGrpcWebTransport } from '@connectrpc/connect-web';
6
- import { create } from '@bufbuild/protobuf';
7
- import { serviceDesc, messageDesc, fileDesc } from '@bufbuild/protobuf/codegenv2';
8
- import { Data, Effect, pipe, Context, flow, Layer, Schedule, Duration } from 'effect';
9
-
10
- var __defProp = Object.defineProperty;
11
- var __export = (target, all) => {
12
- for (var name in all)
13
- __defProp(target, name, { get: all[name], enumerable: true });
14
- };
15
-
16
- // src/poseidon2.ts
17
- var PRIME = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001n;
18
- var NULLIFIER_DOMAIN = 0xdeadn;
19
- var ADDRESS_DOMAIN = 0xdeafn;
20
- var RC_EXT_0 = [
21
- [
22
- 0x1da4d6adfb0d0b494584f763db50a81908580a5f5e295e168b9b8d31770fac4fn,
23
- 0x0946129a2e33b4e819707a56a3b3790eab80d0a0c7a0c63451fab2a59acc074cn
24
- ],
25
- [
26
- 0x2a39b9d5376afd35580abd6952986570867b87303b07140268794dad4b8f82ean,
27
- 0x27605717d1245c20c546b3c7014e5fa3e4a70e66ecd6de5d32448eea5e3069b2n
28
- ],
29
- [
30
- 0x24c896cb2594e17b973653193a470ed7e771ebb09a228d638e50809c03773632n,
31
- 0x0911096c45dd9cda0d61d783957003db6d8701c7869a919ad8042e1b7d597a49n
32
- ]
33
- ];
34
- var RC_INT = [
35
- 0x26ff6166f1e4b99e27eee6d352a8ce26f1daba01aad28021f11f38a70603afdcn,
36
- // 3
37
- 0x008e2faedcf76d08ad6591ff90e50fea79bcb5e18cfb7d954d5b89437bf64b7en,
38
- // 4
39
- 0x19c9da2379b598ace3ad4d1872470830f6184a3cec71eeb632f98820eb353d78n,
40
- // 5
41
- 0x0f7c4eb15d8b0b62a8f6a090ec9610a2ab3dfcdb57e2539aa459a40583dfe96bn,
42
- // 6
43
- 0x18b99417dc26b5e079750eba282362d1d46900b47dd5ff809171588b08ac3983n,
44
- // 7
45
- 0x1ee044081160b3eee2d4493feab82141c73f1c054b76320a8848af08a8d91a26n,
46
- // 8
47
- 0x29bb95c8763efd3e0e87f5df12ee8a150455b6d7a14780d19122220366c258dcn,
48
- // 9
49
- 0x22c23eec9cb13ff8a3ee9a363d740653215e8991f7f9ec12067b4705e9a5c9fbn,
50
- // 10
51
- 0x23589e033a31a667680c8b18926c3be09115c7644c4f905cc7deefc1690b42dcn,
52
- // 11
53
- 0x304e99b887f2e1e92c9c0cde5f2bdd4764f60b98a219f1f0dd64ec938a6a247cn,
54
- // 12
55
- 0x22e817865236ad3a76fbe88bbdf31fcae792f326271d53a3a493b2de7f7d8b4cn,
56
- // 13
57
- 0x10c9efe573e86fa5b238a3f5c70a00bf02bc7dcfcc4878e026b77c881dc8b1c9n,
58
- // 14
59
- 0x0a94f16be920d85f4d6f80e745c6bddbc084f309edffef023ea283c72b89bbb6n,
60
- // 15
61
- 0x23ed72b4d01d14e3c7888fedb770494abc2c1ea81d6465b5df3da0ebcd69101an,
62
- // 16
63
- 0x17c5115640e4cebeed0e6cbb511ac38498df815a77cb162de8d8f1022eb6bb74n,
64
- // 17
65
- 0x2e507fcca290d0d9cf765245750eb04773e09e1fc813959fb99680a82772e4fcn,
66
- // 18
67
- 0x0d4a98999f5b39176af6cce65c8d12162433f055cb71d70dfc8803013292bbbfn,
68
- // 19
69
- 0x238d8022cc09c21ab3c01261a03dc125321d829e22a7a3b7a1bd3c335eccfa21n,
70
- // 20
71
- 0x010cd8e4c2b7051cb81dc8292e35d8e943ce365613d5b39770e454ed9f4ae165n,
72
- // 21
73
- 0x088027e54f2a3604b11178cf0ea3c6aa861173a90fb231238e03539590ecc027n,
74
- // 22
75
- 0x1b840f5311a2b1d4b4cd7aa7e5a9a6d161165468daa938108302b73e464819dbn,
76
- // 23
77
- 0x2bf51a5da1828a1cf9b764b1e16c15929a3a346e44198ea0cb366fcd8db78dc1n,
78
- // 24
79
- 0x206ad089d8d296ffe68a6a86767a7fe726b8872f9c7beef9d56a3a50f6f23827n,
80
- // 25
81
- 0x24d19193171494fa1a54e0a99ac16d05eaec4b6d617c7c199fc07ff88eac550cn,
82
- // 26
83
- 0x1dd654a2ca9d9f24f33d88246a40dfb32c40662278b9c0b995d9f9fbaf152138n,
84
- // 27
85
- 0x0d171025c925f6e259d20ecbd3a601108c85f05b0fe7793b8acf57f3789785e4n,
86
- // 28
87
- 0x055bef435a43aec245cd99ccb0f7c8791d9e8cf2b80d95dd98b9908fed877d55n,
88
- // 29
89
- 0x10d2ac8c61c8a2e88a2a3f42d9359a14be63d0ad4cfd9f203b75765d0e595f0en,
90
- // 30
91
- 0x103479710e70996982a84057ec3ba6b2254d7966ddc41e85296e3d0790dcfa56n,
92
- // 31
93
- 0x2a366f0448fda3c05914ffb48c765da8de96f9aa340db1638225f8372921807bn,
94
- // 32
95
- 0x16be0fb8ef62da17919b6e0378d00594153bb8899aeb686c04626b63285837a4n,
96
- // 33
97
- 0x0417038500e9d06c60abbc7f0d0d24c32dec8a0b2aa5a4d52cfd8c78a15bc370n,
98
- // 34
99
- 0x26a6873b43ffd2ccf66ec6f4493ff9b54f4d76480bc486a3e5a0308fdd013812n,
100
- // 35
101
- 0x0a3314a838f32630a96251914fe5ad262f3db9b2aa8aa9f7391922d36278c498n,
102
- // 36
103
- 0x0fde0c5429a6beb07f462d4821f48f86aeadb46a090b15a044f4b59399027da4n,
104
- // 37
105
- 0x0abc2d5049972a6b9b357e4163793b0bb517e1eb535a984df11a1c89cda2c8a9n,
106
- // 38
107
- 0x0dab51d6e3ebfa661d21722fb21e55051b427a5f173f7f17735205dbb77c464en,
108
- // 39
109
- 0x29c36622598b511d51af6cc37123652fb21be5c2d68fb8efe9b92e70a8c1ae03n,
110
- // 40
111
- 0x2c03ec80adac2a33ae846bc0b700d0bcc41c4096e53ac6990d6bbe7ea2fbc85cn,
112
- // 41
113
- 0x0918fdbe9cf3a59fbdb4c6852d065105317303116017d893b8b521e3cebe1e0dn,
114
- // 42
115
- 0x1f19ec22e69ca33f599dd13cd7e495a8176a79df4f7acf79a9d2135acabe2359n,
116
- // 43
117
- 0x1c4b037c8ae85ee1eb32b872eb7f76928c4c76b29ceb001346447b2911080704n,
118
- // 44
119
- 0x2b68900ed906616d6c826d0bde341766ba3131e04d420de5af0a69c534efd8dbn,
120
- // 45
121
- 0x20ca92aa222fcc69448f8dac653c8daaa180ff6dfb397cef723d4f0c782bc7f0n,
122
- // 46
123
- 0x10d22d05bdff6bb375276fc82057db337045a5ab7ac053941f6186289b66b2b6n,
124
- // 47
125
- 0x0b1ffdbb529367bb98f32ba45784cb435aa910b4a00636d1e5ca79e88bdd6cd9n,
126
- // 48
127
- 0x2da32b38e7984bc2ed757ec705eccf8282c7b4f82e5e515f6f89bcc33022ce9fn,
128
- // 49
129
- 0x042593ad87403f6d2674b8b55a886725b87eb33958031e94d292cecc6abed1bbn,
130
- // 50
131
- 0x181fa1b4d067783a19d7367bf49b3f01051faedab463a6de9308fbd6e7d419f1n,
132
- // 51
133
- 0x15aaa6cc9b7900b15683c95515c26028a8e35b00ed8a815c34927188c60de660n
134
- // 52
135
- ];
136
- var RC_EXT_1 = [
137
- [
138
- 0x1bf28a93209084bbbc63234f057254c280b1a636f5a0eced6787320212f75a7an,
139
- 0x1cdb8c8bee5426f02cd9e229776118f156273b312f805c8e6f8c9d81a620cb6fn
140
- ],
141
- [
142
- 0x08299c0abf196d53162e0facb5f1876f516df2505cc387a0f8ea0e8760d5ca7en,
143
- 0x221643d205fe82778a7b7b58cb65c4962d76c0072cabd1124117269d7c710b8an
144
- ],
145
- [
146
- 0x2d036a95f81cf49bb7a0143a28c88767f6bd10c3f74b22db487920d43343dbffn,
147
- 0x08a50897c06aafe6ea414fb1bceca2267cd4a39486729fbc6d5d1bb7a172ebd2n
148
- ]
149
- ];
150
- function addMod(a, b) {
151
- return ((a + b) % PRIME + PRIME) % PRIME;
152
- }
153
- function mulMod(a, b) {
154
- return (a * b % PRIME + PRIME) % PRIME;
155
- }
156
- function sbox(x) {
157
- const x2 = mulMod(x, x);
158
- const x4 = mulMod(x2, x2);
159
- return mulMod(x4, x);
160
- }
161
- function matMulExternal(s0, s1) {
162
- const sum = addMod(s0, s1);
163
- return [addMod(sum, s0), addMod(sum, s1)];
164
- }
165
- function matMulInternal(s0, s1) {
166
- const sum = addMod(s0, s1);
167
- return [addMod(s0, sum), addMod(addMod(s1, s1), sum)];
168
- }
169
- function permutation(state0, state1) {
170
- let s0 = state0;
171
- let s1 = state1;
172
- [s0, s1] = matMulExternal(s0, s1);
173
- for (let i = 0; i < 3; i++) {
174
- s0 = addMod(s0, RC_EXT_0[i][0]);
175
- s1 = addMod(s1, RC_EXT_0[i][1]);
176
- s0 = sbox(s0);
177
- s1 = sbox(s1);
178
- [s0, s1] = matMulExternal(s0, s1);
179
- }
180
- for (let i = 0; i < 50; i++) {
181
- s0 = addMod(s0, RC_INT[i]);
182
- s0 = sbox(s0);
183
- [s0, s1] = matMulInternal(s0, s1);
184
- }
185
- for (let i = 0; i < 3; i++) {
186
- s0 = addMod(s0, RC_EXT_1[i][0]);
187
- s1 = addMod(s1, RC_EXT_1[i][1]);
188
- s0 = sbox(s0);
189
- s1 = sbox(s1);
190
- [s0, s1] = matMulExternal(s0, s1);
191
- }
192
- return [s0, s1];
193
- }
194
- function poseidon2Hash(inputs) {
195
- let hashState = 0n;
196
- for (const block of inputs) {
197
- const [, permutedState1] = permutation(hashState, block);
198
- hashState = addMod(block, permutedState1);
199
- }
200
- return hashState;
201
- }
202
- function hexToBigInt(hex) {
203
- return BigInt(hex);
204
- }
205
- function validateSecret(secret) {
206
- if (secret >= PRIME) {
207
- throw new Error(
208
- `Secret must be less than the BN254 scalar field prime (${PRIME.toString(16)})`
209
- );
210
- }
211
- if (secret < 0n) {
212
- throw new Error("Secret must be non-negative");
213
- }
214
- }
215
- function addressToBigInt(address) {
216
- return BigInt(address);
217
- }
218
- function computeNullifier(secret, dstChainId) {
219
- const secretBigInt = hexToBigInt(secret);
220
- validateSecret(secretBigInt);
221
- return poseidon2Hash([NULLIFIER_DOMAIN, dstChainId, secretBigInt]);
222
- }
223
- function generatePaymentKey() {
224
- while (true) {
225
- const bytes = new Uint8Array(32);
226
- crypto.getRandomValues(bytes);
227
- const value = BigInt(
228
- "0x" + Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("")
229
- );
230
- if (value < PRIME) {
231
- return "0x" + Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
232
- }
233
- }
234
- }
235
- function computeUnspendableAddress(secret, dstChainId, beneficiaries) {
236
- const secretBigInt = hexToBigInt(secret);
237
- validateSecret(secretBigInt);
238
- const hash = poseidon2Hash([
239
- ADDRESS_DOMAIN,
240
- dstChainId,
241
- secretBigInt,
242
- addressToBigInt(beneficiaries[0]),
243
- addressToBigInt(beneficiaries[1]),
244
- addressToBigInt(beneficiaries[2]),
245
- addressToBigInt(beneficiaries[3])
246
- ]);
247
- const addressMask = (1n << 160n) - 1n;
248
- const addressBigInt = hash & addressMask;
249
- return `0x${addressBigInt.toString(16).padStart(40, "0")}`;
250
- }
251
- var ERC20_ABI = [
252
- {
253
- inputs: [{ name: "account", type: "address" }],
254
- name: "balanceOf",
255
- outputs: [{ name: "", type: "uint256" }],
256
- stateMutability: "view",
257
- type: "function"
258
- },
259
- {
260
- inputs: [],
261
- name: "decimals",
262
- outputs: [{ name: "", type: "uint8" }],
263
- stateMutability: "view",
264
- type: "function"
265
- },
266
- {
267
- inputs: [],
268
- name: "symbol",
269
- outputs: [{ name: "", type: "string" }],
270
- stateMutability: "view",
271
- type: "function"
272
- },
273
- {
274
- inputs: [
275
- { name: "spender", type: "address" },
276
- { name: "amount", type: "uint256" }
277
- ],
278
- name: "approve",
279
- outputs: [{ name: "", type: "bool" }],
280
- stateMutability: "nonpayable",
281
- type: "function"
282
- },
283
- {
284
- inputs: [
285
- { name: "to", type: "address" },
286
- { name: "amount", type: "uint256" }
287
- ],
288
- name: "transfer",
289
- outputs: [{ name: "", type: "bool" }],
290
- stateMutability: "nonpayable",
291
- type: "function"
292
- },
293
- {
294
- inputs: [
295
- { name: "from", type: "address" },
296
- { name: "to", type: "address" },
297
- { name: "amount", type: "uint256" }
298
- ],
299
- name: "transferFrom",
300
- outputs: [{ name: "", type: "bool" }],
301
- stateMutability: "nonpayable",
302
- type: "function"
303
- }
304
- ];
305
- var IBC_STORE_ABI = [
306
- {
307
- inputs: [{ name: "clientId", type: "uint32" }],
308
- name: "getClient",
309
- outputs: [{ name: "", type: "address" }],
310
- stateMutability: "view",
311
- type: "function"
312
- }
313
- ];
314
- var LIGHT_CLIENT_ABI = [
315
- {
316
- inputs: [{ name: "clientId", type: "uint32" }],
317
- name: "getLatestHeight",
318
- outputs: [{ name: "", type: "uint64" }],
319
- stateMutability: "view",
320
- type: "function"
321
- },
322
- {
323
- inputs: [
324
- { name: "clientId", type: "uint32" },
325
- { name: "height", type: "uint64" }
326
- ],
327
- name: "getConsensusState",
328
- outputs: [{ name: "", type: "bytes" }],
329
- stateMutability: "view",
330
- type: "function"
331
- }
332
- ];
333
- var ZASSET_ABI = [
334
- {
335
- inputs: [{ name: "nullifier", type: "uint256" }],
336
- name: "nullifierBalance",
337
- outputs: [{ name: "", type: "uint256" }],
338
- stateMutability: "view",
339
- type: "function"
340
- },
341
- {
342
- inputs: [{ name: "clientId", type: "uint32" }],
343
- name: "counterparty",
344
- outputs: [
345
- {
346
- components: [
347
- { name: "tokenAddressKey", type: "bytes32" },
348
- { name: "balanceSlot", type: "bytes32" }
349
- ],
350
- type: "tuple"
351
- }
352
- ],
353
- stateMutability: "view",
354
- type: "function"
355
- },
356
- {
357
- inputs: [],
358
- name: "ibcHandler",
359
- outputs: [{ name: "", type: "address" }],
360
- stateMutability: "view",
361
- type: "function"
362
- },
363
- {
364
- inputs: [{ name: "clientId", type: "uint32" }],
365
- name: "stateRootIndex",
366
- outputs: [{ name: "", type: "uint256" }],
367
- stateMutability: "view",
368
- type: "function"
369
- },
370
- {
371
- inputs: [],
372
- name: "underlying",
373
- outputs: [{ name: "", type: "address" }],
374
- stateMutability: "view",
375
- type: "function"
376
- },
377
- {
378
- inputs: [{ name: "amount", type: "uint256" }],
379
- name: "deposit",
380
- outputs: [],
381
- stateMutability: "nonpayable",
382
- type: "function"
383
- },
384
- {
385
- inputs: [
386
- { name: "to", type: "address" },
387
- { name: "amount", type: "uint256" }
388
- ],
389
- name: "transfer",
390
- outputs: [{ name: "", type: "bool" }],
391
- stateMutability: "nonpayable",
392
- type: "function"
393
- },
394
- {
395
- inputs: [
396
- { name: "proof", type: "uint256[8]" },
397
- { name: "commitments", type: "uint256[2]" },
398
- { name: "commitmentPok", type: "uint256[2]" },
399
- {
400
- name: "lightClients",
401
- type: "tuple[]",
402
- components: [
403
- { name: "clientId", type: "uint32" },
404
- { name: "height", type: "uint64" }
405
- ]
406
- },
407
- { name: "nullifier", type: "uint256" },
408
- { name: "value", type: "uint256" },
409
- { name: "beneficiary", type: "address" },
410
- { name: "attestedMessage", type: "bytes32" },
411
- { name: "signature", type: "bytes" }
412
- ],
413
- name: "redeem",
414
- outputs: [],
415
- stateMutability: "nonpayable",
416
- type: "function"
417
- },
418
- {
419
- anonymous: false,
420
- inputs: [
421
- { indexed: true, name: "from", type: "address" },
422
- { indexed: true, name: "to", type: "address" },
423
- { indexed: false, name: "value", type: "uint256" }
424
- ],
425
- name: "Transfer",
426
- type: "event"
427
- },
428
- {
429
- anonymous: false,
430
- inputs: [
431
- { indexed: true, name: "nullifier", type: "uint256" },
432
- { indexed: true, name: "redeemAmount", type: "uint256" },
433
- { indexed: true, name: "beneficiary", type: "address" }
434
- ],
435
- name: "Redeemed",
436
- type: "event"
437
- }
438
- ];
439
- var IBC_HANDLER_ABI = [
440
- {
441
- inputs: [
442
- {
443
- components: [
444
- { name: "clientId", type: "uint32" },
445
- { name: "clientMessage", type: "bytes" },
446
- { name: "relayer", type: "address" }
447
- ],
448
- name: "msg_",
449
- type: "tuple"
450
- }
451
- ],
452
- name: "updateClient",
453
- outputs: [],
454
- stateMutability: "nonpayable",
455
- type: "function"
456
- }
457
- ];
458
- var RpcClient = class {
459
- client;
460
- constructor(rpcUrl) {
461
- this.client = createPublicClient({
462
- transport: http(rpcUrl)
463
- });
464
- }
465
- getClient() {
466
- return this.client;
467
- }
468
- async getChainId() {
469
- return BigInt(await this.client.getChainId());
470
- }
471
- async getLatestBlockNumber() {
472
- return this.client.getBlockNumber();
473
- }
474
- async getBalance(tokenAddress, accountAddress, blockNumber) {
475
- return this.client.readContract({
476
- address: tokenAddress,
477
- abi: ERC20_ABI,
478
- functionName: "balanceOf",
479
- args: [accountAddress],
480
- blockNumber
481
- });
482
- }
483
- async getDecimals(tokenAddress) {
484
- return this.client.readContract({
485
- address: tokenAddress,
486
- abi: ERC20_ABI,
487
- functionName: "decimals"
488
- });
489
- }
490
- async getSymbol(tokenAddress) {
491
- return this.client.readContract({
492
- address: tokenAddress,
493
- abi: ERC20_ABI,
494
- functionName: "symbol"
495
- });
496
- }
497
- async getLightClientAddress(ibcStoreAddress, clientId) {
498
- return this.client.readContract({
499
- address: ibcStoreAddress,
500
- abi: IBC_STORE_ABI,
501
- functionName: "getClient",
502
- args: [clientId]
503
- });
504
- }
505
- async getLatestHeight(lightClientAddress, clientId) {
506
- return this.client.readContract({
507
- address: lightClientAddress,
508
- abi: LIGHT_CLIENT_ABI,
509
- functionName: "getLatestHeight",
510
- args: [clientId]
511
- });
512
- }
513
- /**
514
- * Get consensus state, extracting the state root at the given byte index
515
- */
516
- async getConsensusState(lightClientAddress, clientId, height, stateRootIndex) {
517
- const consensusBytes = await this.client.readContract({
518
- address: lightClientAddress,
519
- abi: LIGHT_CLIENT_ABI,
520
- functionName: "getConsensusState",
521
- args: [clientId, height]
522
- });
523
- const bytes = hexToBytes(consensusBytes);
524
- const idx = Number(stateRootIndex);
525
- const stateRoot = bytesToHex(bytes.slice(idx, idx + 32));
526
- return { stateRoot };
527
- }
528
- async getNullifierBalance(zassetAddress, nullifier) {
529
- return this.client.readContract({
530
- address: zassetAddress,
531
- abi: ZASSET_ABI,
532
- functionName: "nullifierBalance",
533
- args: [nullifier]
534
- });
535
- }
536
- async getCounterparty(zassetAddress, clientId) {
537
- const result = await this.client.readContract({
538
- address: zassetAddress,
539
- abi: ZASSET_ABI,
540
- functionName: "counterparty",
541
- args: [clientId]
542
- });
543
- return {
544
- tokenAddressKey: result.tokenAddressKey,
545
- balanceSlot: result.balanceSlot
546
- };
547
- }
548
- async getIbcHandlerAddress(zassetAddress) {
549
- return this.client.readContract({
550
- address: zassetAddress,
551
- abi: ZASSET_ABI,
552
- functionName: "ibcHandler"
553
- });
554
- }
555
- async getStateRootIndex(zassetAddress, clientId) {
556
- return this.client.readContract({
557
- address: zassetAddress,
558
- abi: ZASSET_ABI,
559
- functionName: "stateRootIndex",
560
- args: [clientId]
561
- });
562
- }
563
- async getProof(address, storageKeys, blockNumber) {
564
- return this.client.getProof({
565
- address,
566
- storageKeys,
567
- blockNumber
568
- });
569
- }
570
- async getBlock(blockNumber) {
571
- return this.client.getBlock({ blockNumber });
572
- }
573
- /**
574
- * Get redemption history for a nullifier by querying Redeemed events
575
- */
576
- async getRedemptionHistory(zassetAddress, nullifier, fromBlock, toBlock) {
577
- const logs = await this.client.getLogs({
578
- address: zassetAddress,
579
- event: {
580
- type: "event",
581
- name: "Redeemed",
582
- inputs: [
583
- { indexed: true, name: "nullifier", type: "uint256" },
584
- { indexed: true, name: "redeemAmount", type: "uint256" },
585
- { indexed: true, name: "beneficiary", type: "address" }
586
- ]
587
- },
588
- args: {
589
- nullifier
590
- },
591
- fromBlock: fromBlock ?? "earliest",
592
- toBlock: toBlock ?? "latest"
593
- });
594
- return logs.map((log) => ({
595
- txHash: log.transactionHash,
596
- blockNumber: log.blockNumber,
597
- redeemAmount: log.args.redeemAmount,
598
- beneficiary: log.args.beneficiary
599
- }));
600
- }
601
- };
602
- function computeStorageSlot(address, mappingSlot) {
603
- const paddedAddress = padHex(address, { size: 32 });
604
- const paddedSlot = padHex(toHex(mappingSlot), { size: 32 });
605
- return keccak256(encodePacked(["bytes32", "bytes32"], [paddedAddress, paddedSlot]));
606
- }
607
- async function fetchLightClients(dstClient, zassetAddress, clientIds) {
608
- const ibcHandlerAddress = await dstClient.getIbcHandlerAddress(zassetAddress);
609
- const results = [];
610
- for (const clientId of clientIds) {
611
- try {
612
- const lightClientAddress = await dstClient.getLightClientAddress(
613
- ibcHandlerAddress,
614
- clientId
615
- );
616
- const height = await dstClient.getLatestHeight(lightClientAddress, clientId);
617
- const stateRootIndex = await dstClient.getStateRootIndex(zassetAddress, clientId);
618
- const { stateRoot } = await dstClient.getConsensusState(
619
- lightClientAddress,
620
- clientId,
621
- height,
622
- stateRootIndex
623
- );
624
- results.push({ clientId, height, stateRoot });
625
- } catch {
626
- continue;
627
- }
628
- }
629
- return results;
630
- }
631
- async function fetchMptProof(srcClient, tokenAddress, storageSlot, blockNumber) {
632
- const proof = await srcClient.getProof(tokenAddress, [storageSlot], blockNumber);
633
- let storageProof = [];
634
- let storageValue = "0x0";
635
- if (proof.storageProof.length > 0 && proof.storageProof[0]) {
636
- storageProof = proof.storageProof[0].proof;
637
- storageValue = toHex(proof.storageProof[0].value);
638
- }
639
- return {
640
- accountProof: proof.accountProof,
641
- storageProof,
642
- storageValue,
643
- storageRoot: proof.storageHash
644
- };
645
- }
646
- function deterministicShuffleClients(clients, secret) {
647
- if (clients.length <= 1) {
648
- return [...clients];
649
- }
650
- const secretBytes = hexToBytes(secret);
651
- const heightsBytes = new Uint8Array(clients.length * 8);
652
- for (let i = 0; i < clients.length; i++) {
653
- const view = new DataView(heightsBytes.buffer, i * 8, 8);
654
- view.setBigUint64(0, clients[i].height, false);
655
- }
656
- const combined = new Uint8Array(secretBytes.length + heightsBytes.length);
657
- combined.set(secretBytes, 0);
658
- combined.set(heightsBytes, secretBytes.length);
659
- const seedHex = sha256(combined);
660
- const seed = hexToBytes(seedHex);
661
- const shuffled = [...clients];
662
- let seedIndex = 0;
663
- for (let i = shuffled.length - 1; i > 0; i--) {
664
- const randomByte = seed[seedIndex % seed.length];
665
- seedIndex++;
666
- const j = randomByte % (i + 1);
667
- [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
668
- }
669
- return shuffled;
670
- }
671
- async function signAttestedMessage(message, privateKey) {
672
- const messageBytes = hexToBytes(message);
673
- if (messageBytes.length !== 32) {
674
- throw new Error(`Invalid message length: expected 32 bytes, got ${messageBytes.length}`);
675
- }
676
- const signature = await sign({
677
- hash: message,
678
- privateKey,
679
- to: "hex"
680
- });
681
- return signature;
682
- }
683
- function parseProofJson(proofJsonBytes) {
684
- const jsonStr = new TextDecoder().decode(proofJsonBytes);
685
- const raw = JSON.parse(jsonStr);
686
- const commitments = raw.commitments ?? ["0x0", "0x0"];
687
- return {
688
- proof: raw.proof,
689
- commitments,
690
- commitmentPok: raw.commitmentPok,
691
- publicInputs: raw.publicInputs ?? []
692
- };
693
- }
694
- function proofJsonToRedeemParams(proofJson, metadata) {
695
- const parseBigInt = (s) => {
696
- if (s.startsWith("0x")) {
697
- return hexToBigInt$1(s);
698
- }
699
- return BigInt(s);
700
- };
701
- return {
702
- proof: proofJson.proof.map(parseBigInt),
703
- commitments: proofJson.commitments.map(parseBigInt),
704
- commitmentPok: proofJson.commitmentPok.map(parseBigInt),
705
- lightClients: metadata.lightClients.map((lc) => ({
706
- clientId: lc.clientId,
707
- height: lc.height
708
- })),
709
- nullifier: metadata.nullifier,
710
- value: metadata.value,
711
- beneficiary: metadata.beneficiary,
712
- attestedMessage: metadata.attestedMessage,
713
- signature: metadata.signature
714
- };
715
- }
716
- async function submitRedeem(zassetAddress, params, walletClient) {
717
- if (!walletClient.account) {
718
- throw new Error("WalletClient must have an account");
719
- }
720
- if (!walletClient.chain) {
721
- throw new Error("WalletClient must have a chain configured");
722
- }
723
- const hash = await walletClient.writeContractSync({
724
- address: zassetAddress,
725
- abi: ZASSET_ABI,
726
- functionName: "redeem",
727
- args: [
728
- params.proof,
729
- params.commitments,
730
- params.commitmentPok,
731
- params.lightClients,
732
- params.nullifier,
733
- params.value,
734
- params.beneficiary,
735
- params.attestedMessage,
736
- params.signature
737
- ],
738
- chain: walletClient.chain,
739
- account: walletClient.account
740
- }).then((x) => x.transactionHash);
741
- return hash;
742
- }
743
- function rlpEncodeBlockHeader(block) {
744
- const toRlpHex = (value) => {
745
- if (value === void 0 || value === null || value === 0n || value === 0) {
746
- return "0x";
747
- }
748
- let hex = typeof value === "bigint" ? value.toString(16) : value.toString(16);
749
- if (hex.length % 2 !== 0) {
750
- hex = "0" + hex;
751
- }
752
- return `0x${hex}`;
753
- };
754
- const headerFields = [
755
- block.parentHash,
756
- block.sha3Uncles,
757
- block.miner,
758
- block.stateRoot,
759
- block.transactionsRoot,
760
- block.receiptsRoot,
761
- block.logsBloom ?? "0x" + "00".repeat(256),
762
- toRlpHex(block.difficulty),
763
- toRlpHex(block.number),
764
- toRlpHex(block.gasLimit),
765
- toRlpHex(block.gasUsed),
766
- toRlpHex(block.timestamp),
767
- block.extraData,
768
- block.mixHash ?? "0x0000000000000000000000000000000000000000000000000000000000000000",
769
- block.nonce ?? "0x0000000000000000"
770
- ];
771
- if (block.baseFeePerGas !== void 0 && block.baseFeePerGas !== null) {
772
- headerFields.push(toRlpHex(block.baseFeePerGas));
773
- }
774
- if (block.withdrawalsRoot) {
775
- headerFields.push(block.withdrawalsRoot);
776
- }
777
- if (block.blobGasUsed !== void 0 && block.blobGasUsed !== null) {
778
- headerFields.push(toRlpHex(block.blobGasUsed));
779
- }
780
- if (block.excessBlobGas !== void 0 && block.excessBlobGas !== null) {
781
- headerFields.push(toRlpHex(block.excessBlobGas));
782
- }
783
- if (block.parentBeaconBlockRoot) {
784
- headerFields.push(block.parentBeaconBlockRoot);
785
- }
786
- const blockAny = block;
787
- if (blockAny.requestsHash) {
788
- headerFields.push(blockAny.requestsHash);
789
- }
790
- const rlpEncoded = toRlp(headerFields);
791
- const computedHash = keccak256(rlpEncoded);
792
- if (computedHash !== block.hash) {
793
- throw new Error(
794
- `RLP encoding mismatch: computed hash ${computedHash} does not match block hash ${block.hash}. Block number: ${block.number}, fields count: ${headerFields.length}`
795
- );
796
- }
797
- return rlpEncoded;
798
- }
799
- async function updateLoopbackClient(rpcUrl, ibcHandlerAddress, clientId, height, walletClient) {
800
- if (!walletClient.account) {
801
- throw new Error("WalletClient must have an account");
802
- }
803
- if (!walletClient.chain) {
804
- throw new Error("WalletClient must have a chain configured");
805
- }
806
- const publicClient = createPublicClient({
807
- transport: http(rpcUrl)
808
- });
809
- const chainId = await publicClient.getChainId();
810
- const blockNumber = height === "latest" ? await publicClient.getBlockNumber() : height;
811
- const block = await publicClient.getBlock({ blockNumber });
812
- if (!block.number) {
813
- throw new Error("Block number is null");
814
- }
815
- const rlpEncodedHeader = rlpEncodeBlockHeader(block);
816
- const clientMessage = encodeAbiParameters(
817
- [
818
- { type: "uint64", name: "height" },
819
- { type: "bytes", name: "encodedHeader" }
820
- ],
821
- [block.number, rlpEncodedHeader]
822
- );
823
- let currentBlock = await publicClient.getBlockNumber();
824
- while (currentBlock <= blockNumber) {
825
- await new Promise((resolve) => setTimeout(resolve, 1e3));
826
- currentBlock = await publicClient.getBlockNumber();
827
- }
828
- const txHash = await walletClient.writeContractSync({
829
- address: ibcHandlerAddress,
830
- abi: IBC_HANDLER_ABI,
831
- functionName: "updateClient",
832
- args: [
833
- {
834
- clientId,
835
- clientMessage,
836
- relayer: walletClient.account.address
837
- }
838
- ],
839
- chain: walletClient.chain,
840
- account: walletClient.account
841
- }).then((x) => x.transactionHash);
842
- return {
843
- txHash,
844
- blockNumber: block.number,
845
- stateRoot: block.stateRoot,
846
- chainId: BigInt(chainId)
847
- };
848
- }
849
- async function depositToZAsset(rpcUrl, zAssetAddress, depositAddress, amount, walletClient) {
850
- if (!walletClient.account) {
851
- throw new Error("WalletClient must have an account");
852
- }
853
- if (!walletClient.chain) {
854
- throw new Error("WalletClient must have a chain configured");
855
- }
856
- const publicClient = createPublicClient({
857
- transport: http(rpcUrl)
858
- });
859
- const chainId = await publicClient.getChainId();
860
- const underlyingToken = await publicClient.readContract({
861
- address: zAssetAddress,
862
- abi: ZASSET_ABI,
863
- functionName: "underlying"
864
- });
865
- if (underlyingToken === "0x0000000000000000000000000000000000000000") {
866
- throw new Error("ZAsset is not a wrapped token (underlying is zero address)");
867
- }
868
- const approveReceipt = await walletClient.writeContractSync({
869
- address: underlyingToken,
870
- abi: ERC20_ABI,
871
- functionName: "approve",
872
- args: [zAssetAddress, amount],
873
- chain: walletClient.chain,
874
- account: walletClient.account
875
- });
876
- if (approveReceipt.status === "reverted") {
877
- throw new Error(`Approve transaction reverted: ${approveReceipt.transactionHash}`);
878
- }
879
- const depositReceipt = await walletClient.writeContractSync({
880
- address: zAssetAddress,
881
- abi: ZASSET_ABI,
882
- functionName: "deposit",
883
- args: [amount],
884
- chain: walletClient.chain,
885
- account: walletClient.account
886
- });
887
- if (depositReceipt.status === "reverted") {
888
- throw new Error(`Deposit transaction reverted: ${depositReceipt.transactionHash}`);
889
- }
890
- const transferReceipt = await walletClient.writeContractSync({
891
- address: zAssetAddress,
892
- abi: ZASSET_ABI,
893
- functionName: "transfer",
894
- args: [depositAddress, amount],
895
- chain: walletClient.chain,
896
- account: walletClient.account
897
- });
898
- if (transferReceipt.status === "reverted") {
899
- throw new Error(`Transfer transaction reverted: ${transferReceipt.transactionHash}`);
900
- }
901
- return {
902
- txHash: transferReceipt.transactionHash,
903
- underlyingToken,
904
- chainId: BigInt(chainId)
905
- };
906
- }
907
- var file_prover = /* @__PURE__ */ fileDesc("Cgxwcm92ZXIucHJvdG8SBnByb3ZlciI0CgxQcm9vZlJlcXVlc3QSJAoHd2l0bmVzcxgBIAEoCzITLnByb3Zlci5XaXRuZXNzRGF0YSK1AgoLV2l0bmVzc0RhdGESDgoGc2VjcmV0GAEgASgJEhQKDGRzdF9jaGFpbl9pZBgCIAEoBBIVCg1iZW5lZmljaWFyaWVzGAMgAygJEhMKC2JlbmVmaWNpYXJ5GAQgASgJEhUKDXJlZGVlbV9hbW91bnQYBSABKAkSGAoQYWxyZWFkeV9yZWRlZW1lZBgGIAEoCRIuCg1saWdodF9jbGllbnRzGAcgAygLMhcucHJvdmVyLkxpZ2h0Q2xpZW50RGF0YRIdChVzZWxlY3RlZF9jbGllbnRfaW5kZXgYCCABKA0SJwoJbXB0X3Byb29mGAkgASgLMhQucHJvdmVyLk1QVFByb29mRGF0YRIVCg10b2tlbl9hZGRyZXNzGAogASgJEhQKDG1hcHBpbmdfc2xvdBgLIAEoCSJICg9MaWdodENsaWVudERhdGESEQoJY2xpZW50X2lkGAEgASgNEg4KBmhlaWdodBgCIAEoBBISCgpzdGF0ZV9yb290GAMgASgJImkKDE1QVFByb29mRGF0YRIVCg1hY2NvdW50X3Byb29mGAEgAygJEhUKDXN0b3JhZ2VfcHJvb2YYAiADKAkSFQoNc3RvcmFnZV92YWx1ZRgDIAEoCRIUCgxzdG9yYWdlX3Jvb3QYBCABKAkifAoMUG9sbFJlc3BvbnNlEiIKB3BlbmRpbmcYASABKAsyDy5wcm92ZXIuUGVuZGluZ0gAEhwKBGRvbmUYAiABKAsyDC5wcm92ZXIuRG9uZUgAEiAKBmZhaWxlZBgDIAEoCzIOLnByb3Zlci5GYWlsZWRIAEIICgZyZXN1bHQiCQoHUGVuZGluZyIuCgREb25lEhIKCnByb29mX2pzb24YASABKAwSEgoKY3JlYXRlZF9hdBgCIAEoAyIfCgZGYWlsZWQSFQoNZXJyb3JfbWVzc2FnZRgBIAEoCSIRCg9WZXJpZmllclJlcXVlc3QiLQoQVmVyaWZpZXJSZXNwb25zZRIZChF2ZXJpZmllcl9jb250cmFjdBgBIAEoCTKIAQoNUHJvdmVyU2VydmljZRIyCgRQb2xsEhQucHJvdmVyLlByb29mUmVxdWVzdBoULnByb3Zlci5Qb2xsUmVzcG9uc2USQwoORXhwb3J0VmVyaWZpZXISFy5wcm92ZXIuVmVyaWZpZXJSZXF1ZXN0GhgucHJvdmVyLlZlcmlmaWVyUmVzcG9uc2VCHFoacHJpdmF0ZS10cmFuc2Zlci9hcGkvcHJvdG9iBnByb3RvMw");
908
- var ProofRequestSchema = /* @__PURE__ */ messageDesc(file_prover, 0);
909
- var WitnessDataSchema = /* @__PURE__ */ messageDesc(file_prover, 1);
910
- var LightClientDataSchema = /* @__PURE__ */ messageDesc(file_prover, 2);
911
- var MPTProofDataSchema = /* @__PURE__ */ messageDesc(file_prover, 3);
912
- var ProverService = /* @__PURE__ */ serviceDesc(file_prover, 0);
913
-
914
- // src/prover.ts
915
- var ProverClient = class {
916
- client;
917
- pollIntervalMs;
918
- maxPollAttempts;
919
- constructor(proverUrl, options) {
920
- const transport = createGrpcWebTransport({
921
- baseUrl: proverUrl
922
- });
923
- this.client = createClient(ProverService, transport);
924
- this.pollIntervalMs = options?.pollIntervalMs ?? 2e3;
925
- this.maxPollAttempts = options?.maxPollAttempts ?? 300;
926
- }
927
- /**
928
- * Generate a proof by sending witness data to the prover server
929
- *
930
- * The server handles witness transformation internally, so we send
931
- * the structured WitnessData instead of pre-serialized circuit witness bytes.
932
- */
933
- async generateProof(witness) {
934
- const protoWitness = this.witnessToProto(witness);
935
- const request = create(ProofRequestSchema, {
936
- witness: protoWitness
937
- });
938
- let attempts = 0;
939
- while (attempts < this.maxPollAttempts) {
940
- try {
941
- const response = await this.client.poll(request);
942
- switch (response.result.case) {
943
- case "done":
944
- return {
945
- success: true,
946
- proofJson: response.result.value.proofJson,
947
- createdAt: new Date(Number(response.result.value.createdAt) * 1e3)
948
- };
949
- case "failed":
950
- return {
951
- success: false,
952
- error: response.result.value.errorMessage
953
- };
954
- case "pending":
955
- await this.sleep(this.pollIntervalMs);
956
- attempts++;
957
- break;
958
- default:
959
- await this.sleep(this.pollIntervalMs);
960
- attempts++;
961
- }
962
- } catch (error) {
963
- return {
964
- success: false,
965
- error: `RPC error: ${error instanceof Error ? error.message : String(error)}`
966
- };
967
- }
968
- }
969
- return {
970
- success: false,
971
- error: "Proof generation timed out"
972
- };
973
- }
974
- /**
975
- * Export the verifier contract from the prover server
976
- */
977
- async exportVerifier() {
978
- const response = await this.client.exportVerifier({});
979
- return response.verifierContract;
980
- }
981
- witnessToProto(witness) {
982
- return create(WitnessDataSchema, {
983
- secret: witness.secret,
984
- dstChainId: witness.dstChainId,
985
- beneficiaries: [...witness.beneficiaries],
986
- beneficiary: witness.beneficiary,
987
- redeemAmount: witness.redeemAmount.toString(),
988
- alreadyRedeemed: witness.alreadyRedeemed.toString(),
989
- lightClients: witness.lightClients.map(
990
- (lc) => create(LightClientDataSchema, {
991
- clientId: lc.clientId,
992
- height: lc.height,
993
- stateRoot: lc.stateRoot
994
- })
995
- ),
996
- selectedClientIndex: witness.selectedClientIndex,
997
- mptProof: create(MPTProofDataSchema, {
998
- accountProof: [...witness.mptProof.accountProof],
999
- storageProof: [...witness.mptProof.storageProof],
1000
- storageValue: witness.mptProof.storageValue,
1001
- storageRoot: witness.mptProof.storageRoot
1002
- }),
1003
- tokenAddress: witness.srcZAssetAddress,
1004
- mappingSlot: witness.mappingSlot
1005
- });
1006
- }
1007
- sleep(ms) {
1008
- return new Promise((resolve) => setTimeout(resolve, ms));
1009
- }
1010
- };
1011
-
1012
- // src/attestation.ts
1013
- var AttestationClient = class {
1014
- baseUrl;
1015
- apiKey;
1016
- constructor(baseUrl, apiKey) {
1017
- this.baseUrl = baseUrl.replace(/\/$/, "");
1018
- this.apiKey = apiKey;
1019
- }
1020
- async getAttestation(unspendableAddress, beneficiary) {
1021
- const request = {
1022
- unspendableAddress,
1023
- beneficiary
1024
- };
1025
- const headers = {
1026
- "Content-Type": "application/json"
1027
- };
1028
- headers["x-api-key"] = this.apiKey;
1029
- const response = await fetch(this.baseUrl, {
1030
- method: "POST",
1031
- headers,
1032
- body: JSON.stringify(request)
1033
- });
1034
- if (!response.ok) {
1035
- const errorText = await response.text();
1036
- throw new Error(`Attestation service error: ${response.status} ${errorText}`);
1037
- }
1038
- const data = await response.json();
1039
- const r = data.signature.r.slice(2);
1040
- const s = data.signature.s.slice(2);
1041
- const v = data.signature.v.toString(16).padStart(2, "0");
1042
- const signature = `0x${r}${s}${v}`;
1043
- return {
1044
- attestedMessage: data.hash,
1045
- signature
1046
- };
1047
- }
1048
- };
1049
-
1050
- // src/client.ts
1051
- var client_exports = {};
1052
- __export(client_exports, {
1053
- UnionPrivatePayments: () => UnionPrivatePayments,
1054
- make: () => make,
1055
- waitForBlockCondition: () => waitForBlockCondition
1056
- });
1057
-
1058
- // src/constants/z-asset-registry.ts
1059
- var Z_ASSET_REGISTRY = {
1060
- "8453": {
1061
- "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913": "0xF0000101561619d8A61ABd045F47Af4f41Afe62D"
1062
- }
1063
- };
1064
- var publicClientLayer = (tag) => (...options) => Layer.effect(
1065
- tag,
1066
- pipe(
1067
- Effect.try({
1068
- try: () => V.createPublicClient(...options),
1069
- catch: (err) => new CreatePublicClientError({
1070
- cause: err
1071
- })
1072
- }),
1073
- Effect.map((client) => ({ client }))
1074
- )
1075
- );
1076
- var walletClientLayer = (tag) => (options) => Layer.effect(
1077
- tag,
1078
- pipe(
1079
- Effect.try({
1080
- try: () => V.createWalletClient(options),
1081
- catch: (err) => new CreateWalletClientError({
1082
- cause: err
1083
- })
1084
- }),
1085
- Effect.map((client) => ({ client, account: options.account, chain: options.chain }))
1086
- )
1087
- );
1088
- var WaitForTransactionReceiptError = class extends Data.TaggedError(
1089
- "WaitForTransactionReceiptError"
1090
- ) {
1091
- };
1092
- var waitForTransactionReceipt = Effect.fn("waitForTransactionReceipt")(
1093
- (hash) => pipe(
1094
- PublicClient,
1095
- Effect.andThen(
1096
- ({ client }) => Effect.tryPromise({
1097
- try: () => client.waitForTransactionReceipt({ hash }),
1098
- catch: (err) => new WaitForTransactionReceiptError({
1099
- cause: err
1100
- })
1101
- })
1102
- )
1103
- )
1104
- );
1105
- var readContract = Effect.fn("readContract")(
1106
- (params) => pipe(
1107
- PublicClient,
1108
- Effect.andThen(
1109
- ({ client }) => Effect.tryPromise({
1110
- try: () => client.readContract(params),
1111
- catch: (error) => new ReadContractError({
1112
- cause: error
1113
- })
1114
- })
1115
- )
1116
- )
1117
- );
1118
- var writeContract = Effect.fn("writeContract")(
1119
- (params) => pipe(
1120
- WalletClient,
1121
- Effect.andThen(
1122
- ({ client }) => Effect.tryPromise({
1123
- try: () => client.writeContract(params),
1124
- catch: (error) => new WriteContractError({
1125
- cause: error
1126
- })
1127
- })
1128
- )
1129
- )
1130
- );
1131
- Effect.fn("writeContract")(
1132
- (params) => pipe(
1133
- WalletClient,
1134
- Effect.andThen(
1135
- ({ client }) => Effect.tryPromise({
1136
- try: () => client.writeContract(params),
1137
- catch: (error) => new WriteContractError({
1138
- cause: error
1139
- })
1140
- })
1141
- )
1142
- )
1143
- );
1144
- (class _ChannelDestination extends Context.Tag("@unionlabs/sdk/Evm/ChannelDestination")() {
1145
- static Live = flow(
1146
- _ChannelDestination.of,
1147
- Layer.succeed(this)
1148
- );
1149
- });
1150
- (class _ChannelSource extends Context.Tag("@unionlabs/sdk/Evm/ChannelSource")() {
1151
- static Live = flow(
1152
- _ChannelSource.of,
1153
- Layer.succeed(this)
1154
- );
1155
- });
1156
- (class extends Context.Tag("@unionlabs/sdk/Evm/PublicClientSource")() {
1157
- static Live = publicClientLayer(this);
1158
- });
1159
- (class extends Context.Tag("@unionlabs/sdk/Evm/PublicClientDestination")() {
1160
- static Live = publicClientLayer(this);
1161
- });
1162
- var PublicClient = class extends Context.Tag("@unionlabs/sdk-evm/Evm/PublicClient")() {
1163
- static Live = publicClientLayer(this);
1164
- };
1165
- var WalletClient = class extends Context.Tag("@unionlabs/sdk/Evm/WalletClient")() {
1166
- static Live = walletClientLayer(this);
1167
- };
1168
- var ReadContractError = class extends Data.TaggedError("@unionlabs/sdk/Evm/ReadContractError") {
1169
- };
1170
- var WriteContractError = class extends Data.TaggedError("@unionlabs/sdk/Evm/WriteContractError") {
1171
- };
1172
- (class extends Data.TaggedError("@unionlabs/sdk/Evm/SimulateContractError") {
1173
- });
1174
- var CreatePublicClientError = class extends Data.TaggedError("@unionlabs/sdk/Evm/CreatePublicClientError") {
1175
- };
1176
- var CreateWalletClientError = class extends Data.TaggedError("@unionlabs/sdk/Evm/CreateWalletClientError") {
1177
- };
1178
-
1179
- // src/client.ts
1180
- var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
1181
- var commonRetry = {
1182
- schedule: Schedule.linear(Duration.seconds(2)),
1183
- times: 6
1184
- };
1185
- var make = (options) => {
1186
- const proverUrl = options.proverUrl?.toString() ?? "https://prover.payments.union.build";
1187
- const attestorUrl = options.attestationUrl?.toString() ?? "https://attestor.payments.union.build/functions/v1/attest";
1188
- const zAssetAddress = Z_ASSET_REGISTRY[`${options.chainId}`][options.assetAddress];
1189
- if (!zAssetAddress) throw new Error("Invalid asset address");
1190
- if (!options.attestorApiKey) throw new Error("No attestor API key");
1191
- return new UnionPrivatePayments({
1192
- proverUrl,
1193
- sourceRpcUrl: options.rpcUrl.toString(),
1194
- destinationRpcUrl: options.rpcUrl.toString(),
1195
- srcZAssetAddress: zAssetAddress,
1196
- dstZAssetAddress: zAssetAddress,
1197
- sourceChainId: options.chainId,
1198
- destinationChainId: options.chainId,
1199
- attestorUrl,
1200
- attestorApiKey: options.attestorApiKey
1201
- });
1202
- };
1203
- var UnionPrivatePayments = class {
1204
- config;
1205
- srcClient;
1206
- dstClient;
1207
- proverClient;
1208
- constructor(config) {
1209
- this.config = config;
1210
- this.srcClient = new RpcClient(config.sourceRpcUrl);
1211
- this.dstClient = new RpcClient(config.destinationRpcUrl);
1212
- this.proverClient = new ProverClient(config.proverUrl);
1213
- }
1214
- /**
1215
- * Get the deposit address for a given secret and beneficiaries
1216
- *
1217
- * The returned address is an "unspendable" address derived from the secret.
1218
- * Tokens sent to this address can only be redeemed via ZK proof.
1219
- *
1220
- * @param secret - The 32-byte secret as a hex string
1221
- * @param beneficiaries - Array of 1-4 beneficiary addresses (remaining slots zero-padded)
1222
- * @returns The unspendable deposit address
1223
- */
1224
- getDepositAddress(secret, beneficiaries) {
1225
- const paddedBeneficiaries = this.padBeneficiaries(beneficiaries);
1226
- return computeUnspendableAddress(
1227
- secret,
1228
- this.config.destinationChainId,
1229
- paddedBeneficiaries
1230
- );
1231
- }
1232
- /**
1233
- * Get the nullifier for a given paymentKey
1234
- *
1235
- * The nullifier is used to prevent double-spending. Each (paymentKey, chainId) pair
1236
- * produces a unique nullifier that is recorded on-chain when funds are redeemed.
1237
- *
1238
- * @param paymentKey - The 32-byte paymentKey as a hex string
1239
- * @returns The nullifier as a bigint
1240
- */
1241
- getNullifier(paymentKey) {
1242
- return computeNullifier(paymentKey, this.config.destinationChainId);
1243
- }
1244
- /**
1245
- * Get balance information
1246
- *
1247
- * Returns:
1248
- * - confirmed: balance visible to light client (provable)
1249
- * - redeemed: amount already redeemed via nullifier
1250
- * - available: amount that can be redeemed now (confirmed - redeemed)
1251
- * - pending: deposits not yet visible to light client
1252
- *
1253
- * @param options - Options for getting balance
1254
- * @returns Balance information
1255
- */
1256
- async getBalance(options) {
1257
- const { depositAddress, nullifier, clientId } = options;
1258
- const ibcHandlerAddress = await this.dstClient.getIbcHandlerAddress(
1259
- this.config.dstZAssetAddress
1260
- );
1261
- const lightClientAddress = await this.dstClient.getLightClientAddress(
1262
- ibcHandlerAddress,
1263
- clientId
1264
- );
1265
- const lightClientHeight = await this.dstClient.getLatestHeight(
1266
- lightClientAddress,
1267
- clientId
1268
- );
1269
- const balance = await this.getBalanceAtHeight(
1270
- depositAddress,
1271
- nullifier,
1272
- lightClientHeight
1273
- );
1274
- return {
1275
- ...balance,
1276
- lightClientHeight
1277
- };
1278
- }
1279
- /**
1280
- * Get balance information at a specific block height
1281
- *
1282
- * @param depositAddress - The deposit address (unspendable address)
1283
- * @param nullifier - The nullifier for this secret
1284
- * @param height - The block height to query confirmed balance at
1285
- * @returns Balance information at the given height
1286
- */
1287
- async getBalanceAtHeight(depositAddress, nullifier, height) {
1288
- const latestHeight = await this.srcClient.getLatestBlockNumber();
1289
- const [balanceAtTip, confirmed, redeemed] = await Promise.all([
1290
- this.srcClient.getBalance(this.config.srcZAssetAddress, depositAddress),
1291
- this.srcClient.getBalance(
1292
- this.config.srcZAssetAddress,
1293
- depositAddress,
1294
- height
1295
- ),
1296
- this.dstClient.getNullifierBalance(
1297
- this.config.dstZAssetAddress,
1298
- nullifier
1299
- )
1300
- ]);
1301
- const available = confirmed > redeemed ? confirmed - redeemed : 0n;
1302
- const pending = balanceAtTip > confirmed ? balanceAtTip - confirmed : 0n;
1303
- return {
1304
- confirmed,
1305
- redeemed,
1306
- available,
1307
- pending,
1308
- latestHeight
1309
- };
1310
- }
1311
- /**
1312
- * Generate a proof for redeeming funds
1313
- *
1314
- * This method:
1315
- * 1. Fetches light client data from the destination chain
1316
- * 2. Deterministically shuffles clients for privacy
1317
- * 3. Fetches MPT proof from the source chain
1318
- * 4. Builds the witness data
1319
- * 5. Sends the witness to the prover server
1320
- * 6. Polls until the proof is ready
1321
- *
1322
- * @param secret - The 32-byte secret as a hex string
1323
- * @param beneficiaries - Array of 0-4 beneficiary addresses (empty array = unbounded mode)
1324
- * @param beneficiary - The beneficiary address to redeem to
1325
- * @param amount - Amount to redeem
1326
- * @param clientIds - Light client IDs to include in the proof (for anonymity set)
1327
- * @param selectedClientId - The specific light client ID to use for the proof
1328
- * @returns GenerateProofResult containing proof result and client-side metadata
1329
- */
1330
- async generateProof(secret, beneficiaries, beneficiary, amount, clientIds, selectedClientId) {
1331
- if (!clientIds.includes(selectedClientId)) {
1332
- return {
1333
- proof: {
1334
- success: false,
1335
- error: `selectedClientId ${selectedClientId} not in clientIds`
1336
- }
1337
- };
1338
- }
1339
- if (beneficiary === ZERO_ADDRESS) {
1340
- return {
1341
- proof: {
1342
- success: false,
1343
- error: "Beneficiary address cannot be zero"
1344
- }
1345
- };
1346
- }
1347
- const paddedBeneficiaries = this.padBeneficiaries(beneficiaries);
1348
- const depositAddress = this.getDepositAddress(secret, beneficiaries);
1349
- const lightClients = await fetchLightClients(
1350
- this.dstClient,
1351
- this.config.dstZAssetAddress,
1352
- clientIds
1353
- );
1354
- if (lightClients.length === 0) {
1355
- return {
1356
- proof: {
1357
- success: false,
1358
- error: "No valid light clients found"
1359
- }
1360
- };
1361
- }
1362
- const shuffled = deterministicShuffleClients(lightClients, secret);
1363
- const selectedClientIndex = shuffled.findIndex(
1364
- (c) => c.clientId === selectedClientId
1365
- );
1366
- if (selectedClientIndex === -1) {
1367
- return {
1368
- proof: {
1369
- success: false,
1370
- error: `Client ${selectedClientId} not found after fetching`
1371
- }
1372
- };
1373
- }
1374
- const selectedClient = shuffled[selectedClientIndex];
1375
- const { tokenAddressKey, balanceSlot } = await this.dstClient.getCounterparty(
1376
- this.config.dstZAssetAddress,
1377
- selectedClientId
1378
- );
1379
- const ZERO_BYTES32 = "0x0000000000000000000000000000000000000000000000000000000000000000";
1380
- if (balanceSlot === ZERO_BYTES32 || tokenAddressKey === ZERO_BYTES32) {
1381
- return {
1382
- proof: {
1383
- success: false,
1384
- error: `Light client ${selectedClientId} is not configured as a counterparty on the destination ZAsset. Please call setCounterparty() on the ZAsset contract first.`
1385
- }
1386
- };
1387
- }
1388
- const mappingSlot = hexToBigInt$1(balanceSlot);
1389
- const nullifier = this.getNullifier(secret);
1390
- const balance = await this.getBalanceAtHeight(
1391
- depositAddress,
1392
- nullifier,
1393
- selectedClient.height
1394
- );
1395
- if (amount > balance.available) {
1396
- return {
1397
- proof: {
1398
- success: false,
1399
- error: `Insufficient available balance. Requested: ${amount}, Available: ${balance.available} (Confirmed at height ${selectedClient.height}: ${balance.confirmed}, Already redeemed: ${balance.redeemed})`
1400
- }
1401
- };
1402
- }
1403
- const storageSlot = computeStorageSlot(depositAddress, mappingSlot);
1404
- const mptProof = await fetchMptProof(
1405
- this.srcClient,
1406
- this.config.srcZAssetAddress,
1407
- storageSlot,
1408
- selectedClient.height
1409
- );
1410
- const witness = {
1411
- secret,
1412
- dstChainId: this.config.destinationChainId,
1413
- beneficiaries: paddedBeneficiaries,
1414
- beneficiary,
1415
- redeemAmount: amount,
1416
- alreadyRedeemed: balance.redeemed,
1417
- lightClients: shuffled,
1418
- selectedClientIndex,
1419
- mptProof,
1420
- srcZAssetAddress: this.config.srcZAssetAddress,
1421
- mappingSlot: `0x${mappingSlot.toString(16)}`
1422
- };
1423
- const proofResult = await this.proverClient.generateProof(witness);
1424
- if (proofResult.success) {
1425
- return {
1426
- proof: proofResult,
1427
- metadata: {
1428
- depositAddress,
1429
- beneficiary,
1430
- value: amount,
1431
- lightClients: shuffled,
1432
- nullifier
1433
- }
1434
- };
1435
- }
1436
- return { proof: proofResult };
1437
- }
1438
- /**
1439
- * Export the verifier contract from the prover server
1440
- *
1441
- * The verifier contract is used to verify proofs on-chain.
1442
- * It is circuit-specific and does not change between proofs.
1443
- *
1444
- * @returns The Solidity verifier contract source code
1445
- */
1446
- async exportVerifier() {
1447
- return this.proverClient.exportVerifier();
1448
- }
1449
- /**
1450
- * Get source ZAsset token information
1451
- *
1452
- * @returns Token symbol and decimals
1453
- */
1454
- async getSrcZAssetInfo() {
1455
- const [symbol, decimals] = await Promise.all([
1456
- this.srcClient.getSymbol(this.config.srcZAssetAddress),
1457
- this.srcClient.getDecimals(this.config.srcZAssetAddress)
1458
- ]);
1459
- return { symbol, decimals };
1460
- }
1461
- /**
1462
- * Get destination ZAsset token information
1463
- *
1464
- * @returns Token symbol and decimals
1465
- */
1466
- async getDstZAssetInfo() {
1467
- const [symbol, decimals] = await Promise.all([
1468
- this.dstClient.getSymbol(this.config.dstZAssetAddress),
1469
- this.dstClient.getDecimals(this.config.dstZAssetAddress)
1470
- ]);
1471
- return { symbol, decimals };
1472
- }
1473
- /**
1474
- * Deposit underlying tokens to ZAsset and transfer to deposit address
1475
- *
1476
- * Executes 3 transactions: approve → deposit → transfer.
1477
- * The wallet client must be connected to the source chain.
1478
- *
1479
- * @param secret - The 32-byte secret as a hex string
1480
- * @param beneficiaries - Array of 0-4 beneficiary addresses
1481
- * @param amount - Amount to deposit (in underlying token's smallest unit)
1482
- * @param walletClient - viem WalletClient with account and chain configured
1483
- * @returns Transaction hash, deposit address, underlying token, and chain ID
1484
- */
1485
- async deposit(options) {
1486
- const { paymentKey, beneficiaries, amount, walletClient } = options;
1487
- if (!walletClient.account) {
1488
- throw new Error("WalletClient must have an account");
1489
- }
1490
- if (!walletClient.chain) {
1491
- throw new Error("WalletClient must have a chain configured");
1492
- }
1493
- return Effect.gen(this, function* () {
1494
- const depositAddress = this.getDepositAddress(paymentKey, beneficiaries);
1495
- const underlyingToken = yield* pipe(
1496
- readContract({
1497
- address: this.config.srcZAssetAddress,
1498
- abi: [
1499
- {
1500
- inputs: [],
1501
- name: "underlying",
1502
- outputs: [{ name: "", type: "address" }],
1503
- stateMutability: "view",
1504
- type: "function"
1505
- }
1506
- ],
1507
- functionName: "underlying"
1508
- }),
1509
- Effect.retry(commonRetry),
1510
- Effect.provideService(PublicClient, {
1511
- client: this.srcClient.getClient()
1512
- })
1513
- );
1514
- if (underlyingToken === ZERO_ADDRESS) {
1515
- return yield* Effect.fail(
1516
- Error("ZAsset is not a wrapped token (underlying is zero address)")
1517
- );
1518
- }
1519
- const ERC20_ABI2 = [
1520
- {
1521
- inputs: [
1522
- { name: "spender", type: "address" },
1523
- { name: "amount", type: "uint256" }
1524
- ],
1525
- name: "approve",
1526
- outputs: [{ name: "", type: "bool" }],
1527
- stateMutability: "nonpayable",
1528
- type: "function"
1529
- }
1530
- ];
1531
- const ZASSET_ABI2 = [
1532
- {
1533
- inputs: [{ name: "amount", type: "uint256" }],
1534
- name: "deposit",
1535
- outputs: [],
1536
- stateMutability: "nonpayable",
1537
- type: "function"
1538
- },
1539
- {
1540
- inputs: [
1541
- { name: "to", type: "address" },
1542
- { name: "amount", type: "uint256" }
1543
- ],
1544
- name: "transfer",
1545
- outputs: [{ name: "", type: "bool" }],
1546
- stateMutability: "nonpayable",
1547
- type: "function"
1548
- }
1549
- ];
1550
- const approveHash = yield* pipe(
1551
- writeContract({
1552
- address: underlyingToken,
1553
- abi: ERC20_ABI2,
1554
- functionName: "approve",
1555
- args: [this.config.srcZAssetAddress, amount],
1556
- chain: walletClient.chain,
1557
- account: walletClient.account
1558
- }),
1559
- Effect.retry(commonRetry)
1560
- );
1561
- const approveReceipt = yield* pipe(
1562
- waitForTransactionReceipt(approveHash),
1563
- Effect.retry(commonRetry)
1564
- );
1565
- if (approveReceipt.status === "reverted") {
1566
- return yield* Effect.fail(
1567
- Error(`Approve transaction reverted: ${approveHash}`)
1568
- );
1569
- }
1570
- const depositHash = yield* pipe(
1571
- writeContract({
1572
- address: this.config.srcZAssetAddress,
1573
- abi: ZASSET_ABI2,
1574
- functionName: "deposit",
1575
- args: [amount],
1576
- chain: walletClient.chain,
1577
- account: walletClient.account
1578
- }),
1579
- Effect.retry(commonRetry)
1580
- );
1581
- const depositReceipt = yield* waitForTransactionReceipt(depositHash).pipe(Effect.retry(commonRetry));
1582
- if (depositReceipt.status === "reverted") {
1583
- throw new Error(`Deposit transaction reverted: ${depositHash}`);
1584
- }
1585
- const transferHash = yield* pipe(
1586
- writeContract({
1587
- address: this.config.srcZAssetAddress,
1588
- abi: ZASSET_ABI2,
1589
- functionName: "transfer",
1590
- args: [depositAddress, amount],
1591
- chain: walletClient.chain,
1592
- account: walletClient.account
1593
- }),
1594
- Effect.retry(commonRetry)
1595
- );
1596
- const transferReceipt = yield* waitForTransactionReceipt(transferHash);
1597
- if (transferReceipt.status === "reverted") {
1598
- throw new Error(`Transfer transaction reverted: ${transferHash}`);
1599
- }
1600
- return {
1601
- txHash: transferHash,
1602
- depositAddress,
1603
- underlyingToken,
1604
- chainId: this.config.sourceChainId,
1605
- height: transferReceipt.blockNumber
1606
- };
1607
- }).pipe(
1608
- Effect.provide(
1609
- PublicClient.Live({
1610
- chain: options.walletClient.chain,
1611
- transport: http(this.config.sourceRpcUrl)
1612
- })
1613
- ),
1614
- Effect.provideService(WalletClient, {
1615
- client: options.walletClient,
1616
- account: options.walletClient.account,
1617
- chain: options.walletClient.chain
1618
- }),
1619
- Effect.runPromise
1620
- );
1621
- }
1622
- /**
1623
- * Deposit underlying tokens to ZAsset and transfer to deposit address
1624
- *
1625
- * Executes 3 transactions: approve → deposit → transfer.
1626
- * The wallet client must be connected to the source chain.
1627
- *
1628
- * @param secret - The 32-byte secret as a hex string
1629
- * @param beneficiaries - Array of 0-4 beneficiary addresses
1630
- * @param amount - Amount to deposit (in underlying token's smallest unit)
1631
- * @param walletClient - viem WalletClient with account and chain configured
1632
- * @returns Transaction hash, deposit address, underlying token, and chain ID
1633
- */
1634
- async unsafeDeposit(options) {
1635
- const { paymentKey, beneficiaries, amount, walletClient } = options;
1636
- if (!walletClient.account) {
1637
- throw new Error("WalletClient must have an account");
1638
- }
1639
- if (!walletClient.chain) {
1640
- throw new Error("WalletClient must have a chain configured");
1641
- }
1642
- const depositAddress = this.getDepositAddress(paymentKey, beneficiaries);
1643
- const publicClient = createPublicClient({
1644
- chain: walletClient.chain,
1645
- transport: http(this.config.sourceRpcUrl)
1646
- });
1647
- const underlyingToken = await this.srcClient.getClient().readContract({
1648
- address: this.config.srcZAssetAddress,
1649
- abi: [
1650
- {
1651
- inputs: [],
1652
- name: "underlying",
1653
- outputs: [{ name: "", type: "address" }],
1654
- stateMutability: "view",
1655
- type: "function"
1656
- }
1657
- ],
1658
- functionName: "underlying"
1659
- });
1660
- if (underlyingToken === ZERO_ADDRESS) {
1661
- throw new Error(
1662
- "ZAsset is not a wrapped token (underlying is zero address)"
1663
- );
1664
- }
1665
- const ERC20_ABI2 = [
1666
- {
1667
- inputs: [
1668
- { name: "spender", type: "address" },
1669
- { name: "amount", type: "uint256" }
1670
- ],
1671
- name: "approve",
1672
- outputs: [{ name: "", type: "bool" }],
1673
- stateMutability: "nonpayable",
1674
- type: "function"
1675
- }
1676
- ];
1677
- const ZASSET_ABI2 = [
1678
- {
1679
- inputs: [{ name: "amount", type: "uint256" }],
1680
- name: "deposit",
1681
- outputs: [],
1682
- stateMutability: "nonpayable",
1683
- type: "function"
1684
- },
1685
- {
1686
- inputs: [
1687
- { name: "to", type: "address" },
1688
- { name: "amount", type: "uint256" }
1689
- ],
1690
- name: "transfer",
1691
- outputs: [{ name: "", type: "bool" }],
1692
- stateMutability: "nonpayable",
1693
- type: "function"
1694
- }
1695
- ];
1696
- const approveHash = await walletClient.writeContractSync({
1697
- address: underlyingToken,
1698
- abi: ERC20_ABI2,
1699
- functionName: "approve",
1700
- args: [this.config.srcZAssetAddress, amount],
1701
- chain: walletClient.chain,
1702
- account: walletClient.account
1703
- }).then((x) => x.transactionHash);
1704
- const approveReceipt = await publicClient.waitForTransactionReceipt({
1705
- hash: approveHash
1706
- });
1707
- if (approveReceipt.status === "reverted") {
1708
- throw new Error(`Approve transaction reverted: ${approveHash}`);
1709
- }
1710
- const depositHash = await walletClient.writeContractSync({
1711
- address: this.config.srcZAssetAddress,
1712
- abi: ZASSET_ABI2,
1713
- functionName: "deposit",
1714
- args: [amount],
1715
- chain: walletClient.chain,
1716
- account: walletClient.account
1717
- }).then((x) => x.transactionHash);
1718
- const depositReceipt = await publicClient.waitForTransactionReceipt({
1719
- hash: depositHash
1720
- });
1721
- if (depositReceipt.status === "reverted") {
1722
- throw new Error(`Deposit transaction reverted: ${depositHash}`);
1723
- }
1724
- const transferHash = await walletClient.writeContractSync({
1725
- address: this.config.srcZAssetAddress,
1726
- abi: ZASSET_ABI2,
1727
- functionName: "transfer",
1728
- args: [depositAddress, amount],
1729
- chain: walletClient.chain,
1730
- account: walletClient.account
1731
- }).then((x) => x.transactionHash);
1732
- const transferReceipt = await publicClient.waitForTransactionReceipt({
1733
- hash: transferHash
1734
- });
1735
- if (transferReceipt.status === "reverted") {
1736
- throw new Error(`Transfer transaction reverted: ${transferHash}`);
1737
- }
1738
- return {
1739
- txHash: transferHash,
1740
- depositAddress,
1741
- underlyingToken,
1742
- chainId: this.config.sourceChainId,
1743
- height: transferReceipt.blockNumber
1744
- };
1745
- }
1746
- /**
1747
- * Update loopback light client to a specific block height
1748
- *
1749
- * Fetches the IBC handler address internally from the destination ZAsset.
1750
- * The wallet client must be connected to the destination chain.
1751
- *
1752
- * @returns Transaction hash, block number, state root, and chain ID
1753
- */
1754
- async updateLightClient(options) {
1755
- const { clientId, height, walletClient } = options;
1756
- if (!walletClient.account) {
1757
- throw new Error("WalletClient must have an account");
1758
- }
1759
- if (!walletClient.chain) {
1760
- throw new Error("WalletClient must have a chain configured");
1761
- }
1762
- return Effect.gen(this, function* () {
1763
- const publicClient = createPublicClient({
1764
- chain: walletClient.chain,
1765
- transport: http(this.config.destinationRpcUrl)
1766
- });
1767
- const ibcHandlerAddress = yield* Effect.tryPromise({
1768
- try: () => this.dstClient.getIbcHandlerAddress(this.config.dstZAssetAddress),
1769
- catch: (cause) => Effect.fail(cause)
1770
- });
1771
- const blockNumber = height === "latest" ? yield* pipe(
1772
- Effect.tryPromise(() => publicClient.getBlockNumber()),
1773
- Effect.retry(commonRetry)
1774
- ) : height;
1775
- const block = yield* pipe(
1776
- Effect.tryPromise(() => publicClient.getBlock({ blockNumber })),
1777
- Effect.retry(commonRetry)
1778
- );
1779
- if (!block.number) {
1780
- throw new Error("Block number is null");
1781
- }
1782
- const toRlpHex = (value) => {
1783
- if (value === void 0 || value === null || value === 0n || value === 0) {
1784
- return "0x";
1785
- }
1786
- let hex = typeof value === "bigint" ? value.toString(16) : value.toString(16);
1787
- if (hex.length % 2 !== 0) {
1788
- hex = "0" + hex;
1789
- }
1790
- return `0x${hex}`;
1791
- };
1792
- const headerFields = [
1793
- block.parentHash,
1794
- block.sha3Uncles,
1795
- block.miner,
1796
- block.stateRoot,
1797
- block.transactionsRoot,
1798
- block.receiptsRoot,
1799
- block.logsBloom ?? "0x" + "00".repeat(256),
1800
- toRlpHex(block.difficulty),
1801
- toRlpHex(block.number),
1802
- toRlpHex(block.gasLimit),
1803
- toRlpHex(block.gasUsed),
1804
- toRlpHex(block.timestamp),
1805
- block.extraData,
1806
- block.mixHash ?? "0x0000000000000000000000000000000000000000000000000000000000000000",
1807
- block.nonce ?? "0x0000000000000000"
1808
- ];
1809
- if (block.baseFeePerGas !== void 0 && block.baseFeePerGas !== null) {
1810
- headerFields.push(toRlpHex(block.baseFeePerGas));
1811
- }
1812
- if (block.withdrawalsRoot) {
1813
- headerFields.push(block.withdrawalsRoot);
1814
- }
1815
- if (block.blobGasUsed !== void 0 && block.blobGasUsed !== null) {
1816
- headerFields.push(toRlpHex(block.blobGasUsed));
1817
- }
1818
- if (block.excessBlobGas !== void 0 && block.excessBlobGas !== null) {
1819
- headerFields.push(toRlpHex(block.excessBlobGas));
1820
- }
1821
- if (block.parentBeaconBlockRoot) {
1822
- headerFields.push(block.parentBeaconBlockRoot);
1823
- }
1824
- const blockAny = block;
1825
- if (blockAny.requestsHash) {
1826
- headerFields.push(blockAny.requestsHash);
1827
- }
1828
- const rlpEncoded = toRlp(headerFields);
1829
- const computedHash = keccak256(rlpEncoded);
1830
- if (computedHash !== block.hash) {
1831
- throw new Error(
1832
- `RLP encoding mismatch: computed hash ${computedHash} does not match block hash ${block.hash}`
1833
- );
1834
- }
1835
- const clientMessage = encodeAbiParameters(
1836
- [
1837
- { type: "uint64", name: "height" },
1838
- { type: "bytes", name: "encodedHeader" }
1839
- ],
1840
- [block.number, rlpEncoded]
1841
- );
1842
- const LIGHTCLIENT_ABI = [
1843
- {
1844
- inputs: [
1845
- { name: "caller", type: "address" },
1846
- { name: "clientId", type: "uint32" },
1847
- { name: "clientMessage", type: "bytes" },
1848
- { name: "relayer", type: "address" }
1849
- ],
1850
- name: "updateClient",
1851
- outputs: [],
1852
- stateMutability: "nonpayable",
1853
- type: "function"
1854
- }
1855
- ];
1856
- let currentBlock = yield* pipe(
1857
- Effect.tryPromise(() => publicClient.getBlockNumber()),
1858
- Effect.retry(commonRetry)
1859
- );
1860
- while (currentBlock <= blockNumber) {
1861
- yield* Effect.sleep("1 second");
1862
- currentBlock = yield* Effect.tryPromise(
1863
- () => publicClient.getBlockNumber()
1864
- );
1865
- }
1866
- const loopbackClient = yield* pipe(
1867
- readContract({
1868
- address: ibcHandlerAddress,
1869
- abi: IBC_STORE_ABI,
1870
- functionName: "getClient",
1871
- args: [clientId]
1872
- }),
1873
- Effect.retry(commonRetry)
1874
- );
1875
- const txHash = yield* pipe(
1876
- writeContract({
1877
- address: loopbackClient,
1878
- abi: LIGHTCLIENT_ABI,
1879
- functionName: "updateClient",
1880
- args: [
1881
- walletClient.account.address,
1882
- clientId,
1883
- clientMessage,
1884
- walletClient.account.address
1885
- ],
1886
- chain: walletClient.chain,
1887
- account: walletClient.account
1888
- }),
1889
- Effect.retry(commonRetry)
1890
- );
1891
- const chainId = yield* Effect.sync(() => this.config.destinationChainId);
1892
- return {
1893
- txHash,
1894
- blockNumber: block.number,
1895
- stateRoot: block.stateRoot,
1896
- chainId
1897
- };
1898
- }).pipe(
1899
- Effect.provide(
1900
- PublicClient.Live({
1901
- chain: walletClient.chain,
1902
- transport: http(this.config.destinationRpcUrl)
1903
- })
1904
- ),
1905
- Effect.provideService(WalletClient, {
1906
- client: options.walletClient,
1907
- account: options.walletClient.account,
1908
- chain: options.walletClient.chain
1909
- }),
1910
- Effect.runPromise
1911
- );
1912
- }
1913
- /**
1914
- * Update loopback light client to a specific block height
1915
- *
1916
- * Fetches the IBC handler address internally from the destination ZAsset.
1917
- * The wallet client must be connected to the destination chain.
1918
- *
1919
- * @returns Transaction hash, block number, state root, and chain ID
1920
- */
1921
- async unsafeUpdateLightClient(options) {
1922
- const { clientId, height, walletClient } = options;
1923
- if (!walletClient.account) {
1924
- throw new Error("WalletClient must have an account");
1925
- }
1926
- if (!walletClient.chain) {
1927
- throw new Error("WalletClient must have a chain configured");
1928
- }
1929
- const publicClient = createPublicClient({
1930
- chain: walletClient.chain,
1931
- transport: http(this.config.destinationRpcUrl)
1932
- });
1933
- const ibcHandlerAddress = await this.dstClient.getIbcHandlerAddress(
1934
- this.config.dstZAssetAddress
1935
- );
1936
- const blockNumber = height === "latest" ? await publicClient.getBlockNumber() : height;
1937
- const block = await publicClient.getBlock({ blockNumber });
1938
- if (!block.number) {
1939
- throw new Error("Block number is null");
1940
- }
1941
- const toRlpHex = (value) => {
1942
- if (value === void 0 || value === null || value === 0n || value === 0) {
1943
- return "0x";
1944
- }
1945
- let hex = typeof value === "bigint" ? value.toString(16) : value.toString(16);
1946
- if (hex.length % 2 !== 0) {
1947
- hex = "0" + hex;
1948
- }
1949
- return `0x${hex}`;
1950
- };
1951
- const headerFields = [
1952
- block.parentHash,
1953
- block.sha3Uncles,
1954
- block.miner,
1955
- block.stateRoot,
1956
- block.transactionsRoot,
1957
- block.receiptsRoot,
1958
- block.logsBloom ?? "0x" + "00".repeat(256),
1959
- toRlpHex(block.difficulty),
1960
- toRlpHex(block.number),
1961
- toRlpHex(block.gasLimit),
1962
- toRlpHex(block.gasUsed),
1963
- toRlpHex(block.timestamp),
1964
- block.extraData,
1965
- block.mixHash ?? "0x0000000000000000000000000000000000000000000000000000000000000000",
1966
- block.nonce ?? "0x0000000000000000"
1967
- ];
1968
- if (block.baseFeePerGas !== void 0 && block.baseFeePerGas !== null) {
1969
- headerFields.push(toRlpHex(block.baseFeePerGas));
1970
- }
1971
- if (block.withdrawalsRoot) {
1972
- headerFields.push(block.withdrawalsRoot);
1973
- }
1974
- if (block.blobGasUsed !== void 0 && block.blobGasUsed !== null) {
1975
- headerFields.push(toRlpHex(block.blobGasUsed));
1976
- }
1977
- if (block.excessBlobGas !== void 0 && block.excessBlobGas !== null) {
1978
- headerFields.push(toRlpHex(block.excessBlobGas));
1979
- }
1980
- if (block.parentBeaconBlockRoot) {
1981
- headerFields.push(block.parentBeaconBlockRoot);
1982
- }
1983
- const blockAny = block;
1984
- if (blockAny.requestsHash) {
1985
- headerFields.push(blockAny.requestsHash);
1986
- }
1987
- const rlpEncoded = toRlp(headerFields);
1988
- const computedHash = keccak256(rlpEncoded);
1989
- if (computedHash !== block.hash) {
1990
- throw new Error(
1991
- `RLP encoding mismatch: computed hash ${computedHash} does not match block hash ${block.hash}`
1992
- );
1993
- }
1994
- const clientMessage = encodeAbiParameters(
1995
- [
1996
- { type: "uint64", name: "height" },
1997
- { type: "bytes", name: "encodedHeader" }
1998
- ],
1999
- [block.number, rlpEncoded]
2000
- );
2001
- const LIGHTCLIENT_ABI = [
2002
- {
2003
- inputs: [
2004
- { name: "caller", type: "address" },
2005
- { name: "clientId", type: "uint32" },
2006
- { name: "clientMessage", type: "bytes" },
2007
- { name: "relayer", type: "address" }
2008
- ],
2009
- name: "updateClient",
2010
- outputs: [],
2011
- stateMutability: "nonpayable",
2012
- type: "function"
2013
- }
2014
- ];
2015
- let currentBlock = await publicClient.getBlockNumber();
2016
- while (currentBlock <= blockNumber) {
2017
- await new Promise((resolve) => setTimeout(resolve, 1e3));
2018
- currentBlock = await publicClient.getBlockNumber();
2019
- }
2020
- const loopbackClient = await publicClient.readContract({
2021
- address: ibcHandlerAddress,
2022
- abi: IBC_STORE_ABI,
2023
- functionName: "getClient",
2024
- args: [clientId]
2025
- });
2026
- const txHash = await walletClient.writeContractSync({
2027
- address: loopbackClient,
2028
- abi: LIGHTCLIENT_ABI,
2029
- functionName: "updateClient",
2030
- args: [
2031
- walletClient.account.address,
2032
- clientId,
2033
- clientMessage,
2034
- walletClient.account.address
2035
- ],
2036
- chain: walletClient.chain,
2037
- account: walletClient.account
2038
- }).then((x) => x.transactionHash);
2039
- return {
2040
- txHash,
2041
- blockNumber: block.number,
2042
- stateRoot: block.stateRoot,
2043
- chainId: this.config.destinationChainId
2044
- };
2045
- }
2046
- /**
2047
- * Get redemption history for a secret
2048
- *
2049
- * Queries the Redeemed events filtered by the nullifier derived from the secret.
2050
- * This is a read-only operation that doesn't require a wallet.
2051
- *
2052
- * @param secret - The 32-byte secret as a hex string
2053
- * @param fromBlock - Start block number (default: earliest)
2054
- * @param toBlock - End block number (default: latest)
2055
- * @returns Array of redemption transactions
2056
- */
2057
- getRedemptionHistory(secret, fromBlock, toBlock) {
2058
- return Effect.gen(this, function* () {
2059
- const nullifier = this.getNullifier(secret);
2060
- return yield* pipe(
2061
- Effect.tryPromise(
2062
- () => this.dstClient.getRedemptionHistory(
2063
- this.config.dstZAssetAddress,
2064
- nullifier,
2065
- fromBlock,
2066
- toBlock
2067
- )
2068
- ),
2069
- Effect.retry(commonRetry)
2070
- );
2071
- }).pipe(Effect.runPromise);
2072
- }
2073
- /**
2074
- * Get redemption history for a secret
2075
- *
2076
- * Queries the Redeemed events filtered by the nullifier derived from the secret.
2077
- * This is a read-only operation that doesn't require a wallet.
2078
- *
2079
- * @param secret - The 32-byte secret as a hex string
2080
- * @param fromBlock - Start block number (default: earliest)
2081
- * @param toBlock - End block number (default: latest)
2082
- * @returns Array of redemption transactions
2083
- */
2084
- async unsafeGetRedemptionHistory(secret, fromBlock, toBlock) {
2085
- const nullifier = this.getNullifier(secret);
2086
- return this.dstClient.getRedemptionHistory(
2087
- this.config.dstZAssetAddress,
2088
- nullifier,
2089
- fromBlock,
2090
- toBlock
2091
- );
2092
- }
2093
- /**
2094
- * Full redeem flow: generate proof + get attestation + submit transaction
2095
- *
2096
- * This method orchestrates the entire redemption process:
2097
- * 1. Generates a ZK proof via the prover server
2098
- * 2. Gets attestation from the attestation service
2099
- * 3. Submits the redeem transaction
2100
- *
2101
- * The wallet client must be connected to the destination chain.
2102
- *
2103
- * @returns Transaction hash, proof, and metadata
2104
- */
2105
- redeem(options) {
2106
- const {
2107
- paymentKey,
2108
- beneficiaries,
2109
- beneficiary,
2110
- amount,
2111
- clientIds,
2112
- selectedClientId,
2113
- walletClient,
2114
- unwrap = true
2115
- } = options;
2116
- const attestationUrl = this.config.attestorUrl;
2117
- const attestorApiKey = this.config.attestorApiKey;
2118
- if (!attestationUrl) {
2119
- throw Error(
2120
- "Attestation URL must be provided either in redeem options or ClientOptions"
2121
- );
2122
- }
2123
- if (!attestorApiKey) {
2124
- throw Error(
2125
- "Attestation API key must be provided either in redeem options or ClientOptions"
2126
- );
2127
- }
2128
- if (!walletClient.account) {
2129
- throw Error("WalletClient must have an account");
2130
- }
2131
- if (!walletClient.chain) {
2132
- throw Error("WalletClient must have a chain configured");
2133
- }
2134
- return Effect.gen(this, function* () {
2135
- const proofResult = yield* Effect.tryPromise({
2136
- try: () => this.generateProof(
2137
- paymentKey,
2138
- beneficiaries,
2139
- beneficiary,
2140
- amount,
2141
- clientIds,
2142
- selectedClientId
2143
- ),
2144
- catch: (cause) => Effect.fail(cause)
2145
- }).pipe(Effect.retry(commonRetry));
2146
- if (!proofResult.proof.success || !proofResult.proof.proofJson || !proofResult.metadata) {
2147
- return yield* Effect.fail(
2148
- Error(proofResult.proof.error ?? "Proof generation failed")
2149
- );
2150
- }
2151
- const proofJson = parseProofJson(proofResult.proof.proofJson);
2152
- const metadata = proofResult.metadata;
2153
- const depositAddress = this.getDepositAddress(paymentKey, beneficiaries);
2154
- const attestationClient = new AttestationClient(
2155
- attestationUrl,
2156
- attestorApiKey
2157
- );
2158
- const attestationResponse = yield* Effect.tryPromise({
2159
- try: () => attestationClient.getAttestation(depositAddress, beneficiary),
2160
- catch: (cause) => Effect.fail(cause)
2161
- }).pipe(Effect.retry(commonRetry));
2162
- const redeemParams = proofJsonToRedeemParams(proofJson, {
2163
- lightClients: metadata.lightClients,
2164
- nullifier: metadata.nullifier,
2165
- value: metadata.value,
2166
- beneficiary: metadata.beneficiary,
2167
- attestedMessage: attestationResponse.attestedMessage,
2168
- signature: attestationResponse.signature
2169
- });
2170
- const ZASSET_ABI2 = [
2171
- {
2172
- inputs: [
2173
- { name: "proof", type: "uint256[8]" },
2174
- { name: "commitments", type: "uint256[2]" },
2175
- { name: "commitmentPok", type: "uint256[2]" },
2176
- {
2177
- name: "lightClients",
2178
- type: "tuple[]",
2179
- components: [
2180
- { name: "clientId", type: "uint32" },
2181
- { name: "height", type: "uint64" }
2182
- ]
2183
- },
2184
- { name: "nullifier", type: "uint256" },
2185
- { name: "value", type: "uint256" },
2186
- { name: "beneficiary", type: "address" },
2187
- { name: "attestedMessage", type: "bytes32" },
2188
- { name: "signature", type: "bytes" },
2189
- { name: "unwrap", type: "bool" }
2190
- ],
2191
- name: "redeem",
2192
- outputs: [],
2193
- stateMutability: "nonpayable",
2194
- type: "function"
2195
- }
2196
- ];
2197
- const txHash = yield* pipe(
2198
- writeContract({
2199
- address: this.config.dstZAssetAddress,
2200
- abi: ZASSET_ABI2,
2201
- functionName: "redeem",
2202
- args: [
2203
- redeemParams.proof,
2204
- redeemParams.commitments,
2205
- redeemParams.commitmentPok,
2206
- redeemParams.lightClients,
2207
- redeemParams.nullifier,
2208
- redeemParams.value,
2209
- redeemParams.beneficiary,
2210
- redeemParams.attestedMessage,
2211
- redeemParams.signature,
2212
- unwrap
2213
- ],
2214
- chain: walletClient.chain,
2215
- account: walletClient.account
2216
- }),
2217
- Effect.retry(commonRetry)
2218
- );
2219
- return {
2220
- txHash,
2221
- proof: proofJson,
2222
- metadata
2223
- };
2224
- }).pipe(
2225
- Effect.provide(
2226
- PublicClient.Live({
2227
- chain: options.walletClient.chain,
2228
- transport: http(this.config.destinationRpcUrl)
2229
- })
2230
- ),
2231
- Effect.provideService(WalletClient, {
2232
- client: options.walletClient,
2233
- account: options.walletClient.account,
2234
- chain: options.walletClient.chain
2235
- }),
2236
- Effect.runPromise
2237
- );
2238
- }
2239
- /**
2240
- * Full redeem flow: generate proof + get attestation + submit transaction
2241
- *
2242
- * This method orchestrates the entire redemption process:
2243
- * 1. Generates a ZK proof via the prover server
2244
- * 2. Gets attestation from the attestation service
2245
- * 3. Submits the redeem transaction
2246
- *
2247
- * The wallet client must be connected to the destination chain.
2248
- *
2249
- * @returns Transaction hash, proof, and metadata
2250
- */
2251
- async unsafeRedeem(options) {
2252
- const {
2253
- paymentKey,
2254
- beneficiaries,
2255
- beneficiary,
2256
- amount,
2257
- clientIds,
2258
- selectedClientId,
2259
- walletClient,
2260
- unwrap = true
2261
- } = options;
2262
- const attestationUrl = this.config.attestorUrl;
2263
- const attestorApiKey = this.config.attestorApiKey;
2264
- if (!attestationUrl) {
2265
- throw new Error(
2266
- "Attestation URL must be provided either in redeem options or ClientOptions"
2267
- );
2268
- }
2269
- if (!attestorApiKey) {
2270
- throw new Error(
2271
- "Attestation API key must be provided either in redeem options or ClientOptions"
2272
- );
2273
- }
2274
- if (!walletClient.account) {
2275
- throw new Error("WalletClient must have an account");
2276
- }
2277
- if (!walletClient.chain) {
2278
- throw new Error("WalletClient must have a chain configured");
2279
- }
2280
- const proofResult = await this.generateProof(
2281
- paymentKey,
2282
- beneficiaries,
2283
- beneficiary,
2284
- amount,
2285
- clientIds,
2286
- selectedClientId
2287
- );
2288
- if (!proofResult.proof.success || !proofResult.proof.proofJson || !proofResult.metadata) {
2289
- throw new Error(proofResult.proof.error ?? "Proof generation failed");
2290
- }
2291
- const proofJson = parseProofJson(proofResult.proof.proofJson);
2292
- const metadata = proofResult.metadata;
2293
- const depositAddress = this.getDepositAddress(paymentKey, beneficiaries);
2294
- const attestationClient = new AttestationClient(
2295
- attestationUrl,
2296
- attestorApiKey
2297
- );
2298
- const attestationResponse = await attestationClient.getAttestation(
2299
- depositAddress,
2300
- beneficiary
2301
- );
2302
- const redeemParams = proofJsonToRedeemParams(proofJson, {
2303
- lightClients: metadata.lightClients,
2304
- nullifier: metadata.nullifier,
2305
- value: metadata.value,
2306
- beneficiary: metadata.beneficiary,
2307
- attestedMessage: attestationResponse.attestedMessage,
2308
- signature: attestationResponse.signature
2309
- });
2310
- const publicClient = createPublicClient({
2311
- chain: walletClient.chain,
2312
- transport: http(this.config.destinationRpcUrl)
2313
- });
2314
- const ZASSET_ABI2 = [
2315
- {
2316
- inputs: [
2317
- { name: "proof", type: "uint256[8]" },
2318
- { name: "commitments", type: "uint256[2]" },
2319
- { name: "commitmentPok", type: "uint256[2]" },
2320
- {
2321
- name: "lightClients",
2322
- type: "tuple[]",
2323
- components: [
2324
- { name: "clientId", type: "uint32" },
2325
- { name: "height", type: "uint64" }
2326
- ]
2327
- },
2328
- { name: "nullifier", type: "uint256" },
2329
- { name: "value", type: "uint256" },
2330
- { name: "beneficiary", type: "address" },
2331
- { name: "attestedMessage", type: "bytes32" },
2332
- { name: "signature", type: "bytes" },
2333
- { name: "unwrap", type: "bool" }
2334
- ],
2335
- name: "redeem",
2336
- outputs: [],
2337
- stateMutability: "nonpayable",
2338
- type: "function"
2339
- }
2340
- ];
2341
- const txHash = await walletClient.writeContractSync({
2342
- address: this.config.dstZAssetAddress,
2343
- abi: ZASSET_ABI2,
2344
- functionName: "redeem",
2345
- args: [
2346
- redeemParams.proof,
2347
- redeemParams.commitments,
2348
- redeemParams.commitmentPok,
2349
- redeemParams.lightClients,
2350
- redeemParams.nullifier,
2351
- redeemParams.value,
2352
- redeemParams.beneficiary,
2353
- redeemParams.attestedMessage,
2354
- redeemParams.signature,
2355
- unwrap
2356
- ],
2357
- chain: walletClient.chain,
2358
- account: walletClient.account
2359
- }).then((x) => x.transactionHash);
2360
- const receipt = await publicClient.waitForTransactionReceipt({
2361
- hash: txHash
2362
- });
2363
- if (receipt.status === "reverted") {
2364
- throw new Error(`Redeem transaction reverted: ${txHash}`);
2365
- }
2366
- return {
2367
- txHash,
2368
- proof: proofJson,
2369
- metadata
2370
- };
2371
- }
2372
- /**
2373
- * Pad beneficiaries array to exactly 4 addresses
2374
- * Empty array = unbounded mode (all zeros, any beneficiary allowed)
2375
- */
2376
- padBeneficiaries(beneficiaries) {
2377
- if (beneficiaries.length > 4) {
2378
- throw new Error("Maximum 4 beneficiaries allowed");
2379
- }
2380
- const padded = [
2381
- beneficiaries[0] ?? ZERO_ADDRESS,
2382
- beneficiaries[1] ?? ZERO_ADDRESS,
2383
- beneficiaries[2] ?? ZERO_ADDRESS,
2384
- beneficiaries[3] ?? ZERO_ADDRESS
2385
- ];
2386
- return padded;
2387
- }
2388
- };
2389
- var waitForBlockCondition = (publicClient, predicate, options) => {
2390
- const timeoutMs = options?.timeoutMs ?? 6e4;
2391
- return new Promise((resolve, reject) => {
2392
- let done = false;
2393
- const unwatch = publicClient.watchBlockNumber({
2394
- onBlockNumber(blockNumber) {
2395
- if (done) return;
2396
- if (predicate(blockNumber)) {
2397
- done = true;
2398
- unwatch();
2399
- resolve(blockNumber);
2400
- }
2401
- },
2402
- onError(error) {
2403
- if (done) return;
2404
- done = true;
2405
- unwatch();
2406
- reject(error);
2407
- }
2408
- });
2409
- setTimeout(() => {
2410
- if (done) return;
2411
- done = true;
2412
- unwatch();
2413
- reject(new Error("Timed out waiting for block condition"));
2414
- }, timeoutMs);
2415
- });
2416
- };
2417
-
2418
- export { AttestationClient, ProverClient, RpcClient, UnionPrivatePayments, client_exports, computeNullifier, computeStorageSlot, computeUnspendableAddress, depositToZAsset, deterministicShuffleClients, fetchLightClients, fetchMptProof, generatePaymentKey, parseProofJson, proofJsonToRedeemParams, signAttestedMessage, submitRedeem, updateLoopbackClient, waitForBlockCondition };