@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
@@ -0,0 +1,1222 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.waitForBlockCondition = exports.make = exports.UnionPrivatePayments = void 0;
7
+ var _effect = require("effect");
8
+ var _viem = require("viem");
9
+ var _attestation = require("../attestation.js");
10
+ var _zAssetRegistry = require("../constants/z-asset-registry.js");
11
+ var evm = _interopRequireWildcard(require("../internal/evm.js"));
12
+ var _poseidon = require("../poseidon2.js");
13
+ var _rpc = require("../rpc.js");
14
+ var _prover = require("./prover.js");
15
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
16
+ const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
17
+ const commonRetry = {
18
+ schedule: /*#__PURE__*/_effect.Schedule.linear(/*#__PURE__*/_effect.Duration.seconds(2)),
19
+ times: 6
20
+ };
21
+ /**
22
+ * Construct a {@link UnionPrivatePayments} client.
23
+ *
24
+ * @throws Error if asset is unrecognized.
25
+ * @public
26
+ */
27
+ const make = options => {
28
+ const proverUrl = options.proverUrl?.toString() ?? "https://prover.payments.union.build";
29
+ const attestorUrl = options.attestationUrl?.toString() ?? "https://attestor.payments.union.build/functions/v1/attest";
30
+ const zAssetAddress =
31
+ // @ts-expect-error
32
+ _zAssetRegistry.Z_ASSET_REGISTRY[`${options.chainId}`][options.assetAddress];
33
+ if (!zAssetAddress) throw new Error("Invalid asset address");
34
+ if (!options.attestorApiKey) throw new Error("No attestor API key");
35
+ return new UnionPrivatePayments({
36
+ proverUrl,
37
+ sourceRpcUrl: options.rpcUrl.toString(),
38
+ destinationRpcUrl: options.rpcUrl.toString(),
39
+ srcZAssetAddress: zAssetAddress,
40
+ dstZAssetAddress: zAssetAddress,
41
+ sourceChainId: options.chainId,
42
+ destinationChainId: options.chainId,
43
+ attestorUrl: attestorUrl,
44
+ attestorApiKey: options.attestorApiKey
45
+ });
46
+ };
47
+ /**
48
+ * Union Private Payments client
49
+ *
50
+ * This class provides a high-level interface for performing private transfers
51
+ * using the Union protocol. It handles:
52
+ *
53
+ * - Generating unspendable addresses for deposits
54
+ *
55
+ * - Querying balances (confirmed, pending, redeemed, available)
56
+ *
57
+ * - Building witness data for proof generation
58
+ *
59
+ * - Communicating with the prover server
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * import { UnionPrivatePayments } from '@unionlabs/payments';
64
+ *
65
+ * const client = new UnionPrivatePayments({
66
+ * proverUrl: 'http://localhost:8080',
67
+ * sourceRpcUrl: 'https://eth-mainnet.alchemyapi.io/v2/...',
68
+ * destinationRpcUrl: 'https://arbitrum-mainnet.alchemyapi.io/v2/...',
69
+ * srcZAssetAddress: '0x...', // ZAsset on source chain
70
+ * dstZAssetAddress: '0x...', // ZAsset on destination chain
71
+ * sourceChainId: 1n,
72
+ * destinationChainId: 42161n,
73
+ * });
74
+ *
75
+ * // Generate deposit address
76
+ * const address = client.getDepositAddress(secret, beneficiaries);
77
+ *
78
+ * // Check balance
79
+ * const balance = await client.getBalance({ depositAddress, nullifier, clientId });
80
+ *
81
+ * // Generate proof for redemption
82
+ * const proof = await client.generateProof(secret, beneficiaries, beneficiary, amount, clientIds);
83
+ * ```
84
+ * @public
85
+ */
86
+ exports.make = make;
87
+ class UnionPrivatePayments {
88
+ config;
89
+ srcClient;
90
+ dstClient;
91
+ proverClient;
92
+ constructor(config) {
93
+ this.config = config;
94
+ this.srcClient = new _rpc.RpcClient(config.sourceRpcUrl);
95
+ this.dstClient = new _rpc.RpcClient(config.destinationRpcUrl);
96
+ this.proverClient = new _prover.ProverClient(config.proverUrl);
97
+ }
98
+ /**
99
+ * Get the deposit address for a given secret and beneficiaries
100
+ *
101
+ * The returned address is an "unspendable" address derived from the secret.
102
+ * Tokens sent to this address can only be redeemed via ZK proof.
103
+ *
104
+ * @param secret - The 32-byte secret as a hex string
105
+ * @param beneficiaries - Array of 1-4 beneficiary addresses (remaining slots zero-padded)
106
+ * @returns The unspendable deposit address
107
+ */
108
+ getDepositAddress(secret, beneficiaries) {
109
+ const paddedBeneficiaries = this.padBeneficiaries(beneficiaries);
110
+ return (0, _poseidon.computeUnspendableAddress)(secret, this.config.destinationChainId, paddedBeneficiaries);
111
+ }
112
+ /**
113
+ * Get the nullifier for a given paymentKey
114
+ *
115
+ * The nullifier is used to prevent double-spending. Each (paymentKey, chainId) pair
116
+ * produces a unique nullifier that is recorded on-chain when funds are redeemed.
117
+ *
118
+ * @param paymentKey - The 32-byte paymentKey as a hex string
119
+ * @returns The nullifier as a bigint
120
+ */
121
+ getNullifier(paymentKey) {
122
+ return (0, _poseidon.computeNullifier)(paymentKey, this.config.destinationChainId);
123
+ }
124
+ /**
125
+ * Get balance information
126
+ *
127
+ * Returns:
128
+ * - confirmed: balance visible to light client (provable)
129
+ * - redeemed: amount already redeemed via nullifier
130
+ * - available: amount that can be redeemed now (confirmed - redeemed)
131
+ * - pending: deposits not yet visible to light client
132
+ *
133
+ * @param options - Options for getting balance
134
+ * @returns Balance information
135
+ */
136
+ async getBalance(options) {
137
+ const {
138
+ depositAddress,
139
+ nullifier,
140
+ clientId
141
+ } = options;
142
+ console.log(options);
143
+ console.log({
144
+ dstZAssetAddress: this.config.dstZAssetAddress
145
+ });
146
+ const ibcHandlerAddress = await this.dstClient.getIbcHandlerAddress(this.config.dstZAssetAddress);
147
+ const lightClientAddress = await this.dstClient.getLightClientAddress(ibcHandlerAddress, clientId);
148
+ const lightClientHeight = await this.dstClient.getLatestHeight(lightClientAddress, clientId);
149
+ const balance = await this.getBalanceAtHeight(depositAddress, nullifier, lightClientHeight);
150
+ return {
151
+ ...balance,
152
+ lightClientHeight
153
+ };
154
+ }
155
+ /**
156
+ * Get balance information at a specific block height
157
+ *
158
+ * @param depositAddress - The deposit address (unspendable address)
159
+ * @param nullifier - The nullifier for this secret
160
+ * @param height - The block height to query confirmed balance at
161
+ * @returns Balance information at the given height
162
+ */
163
+ async getBalanceAtHeight(depositAddress, nullifier, height) {
164
+ const latestHeight = await this.srcClient.getLatestBlockNumber();
165
+ const [balanceAtTip, confirmed, redeemed] = await Promise.all([this.srcClient.getBalance(this.config.srcZAssetAddress, depositAddress), this.srcClient.getBalance(this.config.srcZAssetAddress, depositAddress, height), this.dstClient.getNullifierBalance(this.config.dstZAssetAddress, nullifier)]);
166
+ const available = confirmed > redeemed ? confirmed - redeemed : 0n;
167
+ const pending = balanceAtTip > confirmed ? balanceAtTip - confirmed : 0n;
168
+ return {
169
+ confirmed,
170
+ redeemed,
171
+ available,
172
+ pending,
173
+ latestHeight
174
+ };
175
+ }
176
+ /**
177
+ * Generate a proof for redeeming funds
178
+ *
179
+ * This method:
180
+ * 1. Fetches light client data from the destination chain
181
+ * 2. Deterministically shuffles clients for privacy
182
+ * 3. Fetches MPT proof from the source chain
183
+ * 4. Builds the witness data
184
+ * 5. Sends the witness to the prover server
185
+ * 6. Polls until the proof is ready
186
+ *
187
+ * @param secret - The 32-byte secret as a hex string
188
+ * @param beneficiaries - Array of 0-4 beneficiary addresses (empty array = unbounded mode)
189
+ * @param beneficiary - The beneficiary address to redeem to
190
+ * @param amount - Amount to redeem
191
+ * @param clientIds - Light client IDs to include in the proof (for anonymity set)
192
+ * @param selectedClientId - The specific light client ID to use for the proof
193
+ * @returns GenerateProofResult containing proof result and client-side metadata
194
+ */
195
+ async generateProof(secret, beneficiaries, beneficiary, amount, clientIds, selectedClientId) {
196
+ // Validate inputs
197
+ if (!clientIds.includes(selectedClientId)) {
198
+ return {
199
+ proof: {
200
+ success: false,
201
+ error: `selectedClientId ${selectedClientId} not in clientIds`
202
+ }
203
+ };
204
+ }
205
+ if (beneficiary === ZERO_ADDRESS) {
206
+ return {
207
+ proof: {
208
+ success: false,
209
+ error: "Beneficiary address cannot be zero"
210
+ }
211
+ };
212
+ }
213
+ const paddedBeneficiaries = this.padBeneficiaries(beneficiaries);
214
+ const depositAddress = this.getDepositAddress(secret, beneficiaries);
215
+ const lightClients = await (0, _rpc.fetchLightClients)(this.dstClient, this.config.dstZAssetAddress, clientIds);
216
+ if (lightClients.length === 0) {
217
+ return {
218
+ proof: {
219
+ success: false,
220
+ error: "No valid light clients found"
221
+ }
222
+ };
223
+ }
224
+ // Deterministic shuffle: same secret always produces the same ordering for privacy
225
+ const shuffled = (0, _rpc.deterministicShuffleClients)(lightClients, secret);
226
+ const selectedClientIndex = shuffled.findIndex(c => c.clientId === selectedClientId);
227
+ if (selectedClientIndex === -1) {
228
+ return {
229
+ proof: {
230
+ success: false,
231
+ error: `Client ${selectedClientId} not found after fetching`
232
+ }
233
+ };
234
+ }
235
+ const selectedClient = shuffled[selectedClientIndex];
236
+ const {
237
+ tokenAddressKey,
238
+ balanceSlot
239
+ } = await this.dstClient.getCounterparty(this.config.dstZAssetAddress, selectedClientId);
240
+ // Check if counterparty is configured for this light client
241
+ const ZERO_BYTES32 = "0x0000000000000000000000000000000000000000000000000000000000000000";
242
+ if (balanceSlot === ZERO_BYTES32 || tokenAddressKey === ZERO_BYTES32) {
243
+ return {
244
+ proof: {
245
+ success: false,
246
+ error: `Light client ${selectedClientId} is not configured as a counterparty on the destination ZAsset. ` + `Please call setCounterparty() on the ZAsset contract first.`
247
+ }
248
+ };
249
+ }
250
+ const mappingSlot = (0, _viem.hexToBigInt)(balanceSlot);
251
+ const nullifier = this.getNullifier(secret);
252
+ // Check balance at the selected light client's height
253
+ const balance = await this.getBalanceAtHeight(depositAddress, nullifier, selectedClient.height);
254
+ if (amount > balance.available) {
255
+ return {
256
+ proof: {
257
+ success: false,
258
+ error: `Insufficient available balance. Requested: ${amount}, Available: ${balance.available} ` + `(Confirmed at height ${selectedClient.height}: ${balance.confirmed}, Already redeemed: ${balance.redeemed})`
259
+ }
260
+ };
261
+ }
262
+ const storageSlot = (0, _rpc.computeStorageSlot)(depositAddress, mappingSlot);
263
+ const mptProof = await (0, _rpc.fetchMptProof)(this.srcClient, this.config.srcZAssetAddress, storageSlot, selectedClient.height);
264
+ const witness = {
265
+ secret,
266
+ dstChainId: this.config.destinationChainId,
267
+ beneficiaries: paddedBeneficiaries,
268
+ beneficiary,
269
+ redeemAmount: amount,
270
+ alreadyRedeemed: balance.redeemed,
271
+ lightClients: shuffled,
272
+ selectedClientIndex,
273
+ mptProof,
274
+ srcZAssetAddress: this.config.srcZAssetAddress,
275
+ mappingSlot: `0x${mappingSlot.toString(16)}`
276
+ };
277
+ const proofResult = await this.proverClient.generateProof(witness);
278
+ if (proofResult.success) {
279
+ return {
280
+ proof: proofResult,
281
+ metadata: {
282
+ depositAddress,
283
+ beneficiary,
284
+ value: amount,
285
+ lightClients: shuffled,
286
+ nullifier
287
+ }
288
+ };
289
+ }
290
+ return {
291
+ proof: proofResult
292
+ };
293
+ }
294
+ /**
295
+ * Export the verifier contract from the prover server
296
+ *
297
+ * The verifier contract is used to verify proofs on-chain.
298
+ * It is circuit-specific and does not change between proofs.
299
+ *
300
+ * @returns The Solidity verifier contract source code
301
+ */
302
+ async exportVerifier() {
303
+ return this.proverClient.exportVerifier();
304
+ }
305
+ /**
306
+ * Get source ZAsset token information
307
+ *
308
+ * @returns Token symbol and decimals
309
+ */
310
+ async getSrcZAssetInfo() {
311
+ const [symbol, decimals] = await Promise.all([this.srcClient.getSymbol(this.config.srcZAssetAddress), this.srcClient.getDecimals(this.config.srcZAssetAddress)]);
312
+ return {
313
+ symbol,
314
+ decimals
315
+ };
316
+ }
317
+ /**
318
+ * Get destination ZAsset token information
319
+ *
320
+ * @returns Token symbol and decimals
321
+ */
322
+ async getDstZAssetInfo() {
323
+ const [symbol, decimals] = await Promise.all([this.dstClient.getSymbol(this.config.dstZAssetAddress), this.dstClient.getDecimals(this.config.dstZAssetAddress)]);
324
+ return {
325
+ symbol,
326
+ decimals
327
+ };
328
+ }
329
+ /**
330
+ * Deposit underlying tokens to ZAsset and transfer to deposit address
331
+ *
332
+ * Executes 3 transactions: approve → deposit → transfer.
333
+ * The wallet client must be connected to the source chain.
334
+ *
335
+ * @param secret - The 32-byte secret as a hex string
336
+ * @param beneficiaries - Array of 0-4 beneficiary addresses
337
+ * @param amount - Amount to deposit (in underlying token's smallest unit)
338
+ * @param walletClient - viem WalletClient with account and chain configured
339
+ * @returns Transaction hash, deposit address, underlying token, and chain ID
340
+ */
341
+ async deposit(options) {
342
+ const {
343
+ paymentKey,
344
+ beneficiaries,
345
+ amount,
346
+ walletClient
347
+ } = options;
348
+ if (!walletClient.account) {
349
+ throw new Error("WalletClient must have an account");
350
+ }
351
+ if (!walletClient.chain) {
352
+ throw new Error("WalletClient must have a chain configured");
353
+ }
354
+ return _effect.Effect.gen(this, function* () {
355
+ const depositAddress = this.getDepositAddress(paymentKey, beneficiaries);
356
+ // Get underlying token address
357
+ const underlyingToken = yield* (0, _effect.pipe)(evm.readContract({
358
+ address: this.config.srcZAssetAddress,
359
+ abi: [{
360
+ inputs: [],
361
+ name: "underlying",
362
+ outputs: [{
363
+ name: "",
364
+ type: "address"
365
+ }],
366
+ stateMutability: "view",
367
+ type: "function"
368
+ }],
369
+ functionName: "underlying"
370
+ }), _effect.Effect.retry(commonRetry), _effect.Effect.provideService(evm.PublicClient, {
371
+ client: this.srcClient.getClient()
372
+ }));
373
+ if (underlyingToken === ZERO_ADDRESS) {
374
+ return yield* _effect.Effect.fail(Error("ZAsset is not a wrapped token (underlying is zero address)"));
375
+ }
376
+ const ERC20_ABI = [{
377
+ inputs: [{
378
+ name: "spender",
379
+ type: "address"
380
+ }, {
381
+ name: "amount",
382
+ type: "uint256"
383
+ }],
384
+ name: "approve",
385
+ outputs: [{
386
+ name: "",
387
+ type: "bool"
388
+ }],
389
+ stateMutability: "nonpayable",
390
+ type: "function"
391
+ }];
392
+ const ZASSET_ABI = [{
393
+ inputs: [{
394
+ name: "amount",
395
+ type: "uint256"
396
+ }],
397
+ name: "deposit",
398
+ outputs: [],
399
+ stateMutability: "nonpayable",
400
+ type: "function"
401
+ }, {
402
+ inputs: [{
403
+ name: "to",
404
+ type: "address"
405
+ }, {
406
+ name: "amount",
407
+ type: "uint256"
408
+ }],
409
+ name: "transfer",
410
+ outputs: [{
411
+ name: "",
412
+ type: "bool"
413
+ }],
414
+ stateMutability: "nonpayable",
415
+ type: "function"
416
+ }];
417
+ // 1. Approve ZAsset to spend underlying tokens
418
+ const approveHash = yield* (0, _effect.pipe)(evm.writeContract({
419
+ address: underlyingToken,
420
+ abi: ERC20_ABI,
421
+ functionName: "approve",
422
+ args: [this.config.srcZAssetAddress, amount],
423
+ chain: walletClient.chain,
424
+ account: walletClient.account
425
+ }), _effect.Effect.retry(commonRetry));
426
+ const approveReceipt = yield* (0, _effect.pipe)(evm.waitForTransactionReceipt(approveHash), _effect.Effect.retry(commonRetry));
427
+ if (approveReceipt.status === "reverted") {
428
+ return yield* _effect.Effect.fail(Error(`Approve transaction reverted: ${approveHash}`));
429
+ }
430
+ // 2. Deposit underlying to get ZAsset
431
+ const depositHash = yield* (0, _effect.pipe)(evm.writeContract({
432
+ address: this.config.srcZAssetAddress,
433
+ abi: ZASSET_ABI,
434
+ functionName: "deposit",
435
+ args: [amount],
436
+ chain: walletClient.chain,
437
+ account: walletClient.account
438
+ }), _effect.Effect.retry(commonRetry));
439
+ const depositReceipt = yield* evm.waitForTransactionReceipt(depositHash).pipe(_effect.Effect.retry(commonRetry));
440
+ if (depositReceipt.status === "reverted") {
441
+ throw new Error(`Deposit transaction reverted: ${depositHash}`);
442
+ }
443
+ // 3. Transfer ZAsset to deposit address
444
+ const transferHash = yield* (0, _effect.pipe)(evm.writeContract({
445
+ address: this.config.srcZAssetAddress,
446
+ abi: ZASSET_ABI,
447
+ functionName: "transfer",
448
+ args: [depositAddress, amount],
449
+ chain: walletClient.chain,
450
+ account: walletClient.account
451
+ }), _effect.Effect.retry(commonRetry));
452
+ const transferReceipt = yield* evm.waitForTransactionReceipt(transferHash);
453
+ if (transferReceipt.status === "reverted") {
454
+ throw new Error(`Transfer transaction reverted: ${transferHash}`);
455
+ }
456
+ return {
457
+ txHash: transferHash,
458
+ depositAddress,
459
+ underlyingToken,
460
+ chainId: this.config.sourceChainId,
461
+ height: transferReceipt.blockNumber
462
+ };
463
+ }).pipe(_effect.Effect.provide(evm.PublicClient.Live({
464
+ chain: options.walletClient.chain,
465
+ transport: (0, _viem.http)(this.config.sourceRpcUrl)
466
+ })), _effect.Effect.provideService(evm.WalletClient, {
467
+ client: options.walletClient,
468
+ account: options.walletClient.account,
469
+ chain: options.walletClient.chain
470
+ }), _effect.Effect.runPromise);
471
+ }
472
+ /**
473
+ * Deposit underlying tokens to ZAsset and transfer to deposit address
474
+ *
475
+ * Executes 3 transactions: approve → deposit → transfer.
476
+ * The wallet client must be connected to the source chain.
477
+ *
478
+ * @param secret - The 32-byte secret as a hex string
479
+ * @param beneficiaries - Array of 0-4 beneficiary addresses
480
+ * @param amount - Amount to deposit (in underlying token's smallest unit)
481
+ * @param walletClient - viem WalletClient with account and chain configured
482
+ * @returns Transaction hash, deposit address, underlying token, and chain ID
483
+ */
484
+ async unsafeDeposit(options) {
485
+ const {
486
+ paymentKey,
487
+ beneficiaries,
488
+ amount,
489
+ walletClient
490
+ } = options;
491
+ if (!walletClient.account) {
492
+ throw new Error("WalletClient must have an account");
493
+ }
494
+ if (!walletClient.chain) {
495
+ throw new Error("WalletClient must have a chain configured");
496
+ }
497
+ const depositAddress = this.getDepositAddress(paymentKey, beneficiaries);
498
+ const publicClient = (0, _viem.createPublicClient)({
499
+ chain: walletClient.chain,
500
+ transport: (0, _viem.http)(this.config.sourceRpcUrl)
501
+ });
502
+ // Get underlying token address
503
+ const underlyingToken = await this.srcClient.getClient().readContract({
504
+ address: this.config.srcZAssetAddress,
505
+ abi: [{
506
+ inputs: [],
507
+ name: "underlying",
508
+ outputs: [{
509
+ name: "",
510
+ type: "address"
511
+ }],
512
+ stateMutability: "view",
513
+ type: "function"
514
+ }],
515
+ functionName: "underlying"
516
+ });
517
+ if (underlyingToken === ZERO_ADDRESS) {
518
+ throw new Error("ZAsset is not a wrapped token (underlying is zero address)");
519
+ }
520
+ const ERC20_ABI = [{
521
+ inputs: [{
522
+ name: "spender",
523
+ type: "address"
524
+ }, {
525
+ name: "amount",
526
+ type: "uint256"
527
+ }],
528
+ name: "approve",
529
+ outputs: [{
530
+ name: "",
531
+ type: "bool"
532
+ }],
533
+ stateMutability: "nonpayable",
534
+ type: "function"
535
+ }];
536
+ const ZASSET_ABI = [{
537
+ inputs: [{
538
+ name: "amount",
539
+ type: "uint256"
540
+ }],
541
+ name: "deposit",
542
+ outputs: [],
543
+ stateMutability: "nonpayable",
544
+ type: "function"
545
+ }, {
546
+ inputs: [{
547
+ name: "to",
548
+ type: "address"
549
+ }, {
550
+ name: "amount",
551
+ type: "uint256"
552
+ }],
553
+ name: "transfer",
554
+ outputs: [{
555
+ name: "",
556
+ type: "bool"
557
+ }],
558
+ stateMutability: "nonpayable",
559
+ type: "function"
560
+ }];
561
+ // 1. Approve ZAsset to spend underlying tokens
562
+ const approveHash = await walletClient.writeContractSync({
563
+ address: underlyingToken,
564
+ abi: ERC20_ABI,
565
+ functionName: "approve",
566
+ args: [this.config.srcZAssetAddress, amount],
567
+ chain: walletClient.chain,
568
+ account: walletClient.account
569
+ }).then(x => x.transactionHash);
570
+ const approveReceipt = await publicClient.waitForTransactionReceipt({
571
+ hash: approveHash
572
+ });
573
+ if (approveReceipt.status === "reverted") {
574
+ throw new Error(`Approve transaction reverted: ${approveHash}`);
575
+ }
576
+ // 2. Deposit underlying to get ZAsset
577
+ const depositHash = await walletClient.writeContractSync({
578
+ address: this.config.srcZAssetAddress,
579
+ abi: ZASSET_ABI,
580
+ functionName: "deposit",
581
+ args: [amount],
582
+ chain: walletClient.chain,
583
+ account: walletClient.account
584
+ }).then(x => x.transactionHash);
585
+ const depositReceipt = await publicClient.waitForTransactionReceipt({
586
+ hash: depositHash
587
+ });
588
+ if (depositReceipt.status === "reverted") {
589
+ throw new Error(`Deposit transaction reverted: ${depositHash}`);
590
+ }
591
+ // 3. Transfer ZAsset to deposit address
592
+ const transferHash = await walletClient.writeContractSync({
593
+ address: this.config.srcZAssetAddress,
594
+ abi: ZASSET_ABI,
595
+ functionName: "transfer",
596
+ args: [depositAddress, amount],
597
+ chain: walletClient.chain,
598
+ account: walletClient.account
599
+ }).then(x => x.transactionHash);
600
+ const transferReceipt = await publicClient.waitForTransactionReceipt({
601
+ hash: transferHash
602
+ });
603
+ if (transferReceipt.status === "reverted") {
604
+ throw new Error(`Transfer transaction reverted: ${transferHash}`);
605
+ }
606
+ return {
607
+ txHash: transferHash,
608
+ depositAddress,
609
+ underlyingToken,
610
+ chainId: this.config.sourceChainId,
611
+ height: transferReceipt.blockNumber
612
+ };
613
+ }
614
+ /**
615
+ * Update loopback light client to a specific block height
616
+ *
617
+ * Fetches the IBC handler address internally from the destination ZAsset.
618
+ * The wallet client must be connected to the destination chain.
619
+ *
620
+ * @returns Transaction hash, block number, state root, and chain ID
621
+ */
622
+ async updateLightClient(options) {
623
+ const {
624
+ clientId,
625
+ height,
626
+ walletClient
627
+ } = options;
628
+ if (!walletClient.account) {
629
+ throw new Error("WalletClient must have an account");
630
+ }
631
+ if (!walletClient.chain) {
632
+ throw new Error("WalletClient must have a chain configured");
633
+ }
634
+ return _effect.Effect.gen(this, function* () {
635
+ const publicClient = (0, _viem.createPublicClient)({
636
+ chain: walletClient.chain,
637
+ transport: (0, _viem.http)(this.config.destinationRpcUrl)
638
+ });
639
+ // Get IBC handler address from ZAsset
640
+ const ibcHandlerAddress = yield* _effect.Effect.tryPromise({
641
+ try: () => this.dstClient.getIbcHandlerAddress(this.config.dstZAssetAddress),
642
+ catch: cause => _effect.Effect.fail(cause)
643
+ });
644
+ // Get the block number
645
+ const blockNumber = height === "latest" ? yield* (0, _effect.pipe)(_effect.Effect.tryPromise(() => publicClient.getBlockNumber()), _effect.Effect.retry(commonRetry)) : height;
646
+ // Get the block for metadata
647
+ const block = yield* (0, _effect.pipe)(_effect.Effect.tryPromise(() => publicClient.getBlock({
648
+ blockNumber
649
+ })), _effect.Effect.retry(commonRetry));
650
+ if (!block.number) {
651
+ throw new Error("Block number is null");
652
+ }
653
+ // Helper to convert bigint/number to minimal RLP hex encoding
654
+ const toRlpHex = value => {
655
+ if (value === undefined || value === null || value === 0n || value === 0) {
656
+ return "0x";
657
+ }
658
+ let hex = typeof value === "bigint" ? value.toString(16) : value.toString(16);
659
+ if (hex.length % 2 !== 0) {
660
+ hex = "0" + hex;
661
+ }
662
+ return `0x${hex}`;
663
+ };
664
+ // Build header fields in order (pre-merge + post-merge fields)
665
+ const headerFields = [block.parentHash, block.sha3Uncles, block.miner, block.stateRoot, block.transactionsRoot, block.receiptsRoot, block.logsBloom ?? "0x" + "00".repeat(256), toRlpHex(block.difficulty), toRlpHex(block.number), toRlpHex(block.gasLimit), toRlpHex(block.gasUsed), toRlpHex(block.timestamp), block.extraData, block.mixHash ?? "0x0000000000000000000000000000000000000000000000000000000000000000", block.nonce ?? "0x0000000000000000"];
666
+ // Post-merge fields
667
+ if (block.baseFeePerGas !== undefined && block.baseFeePerGas !== null) {
668
+ headerFields.push(toRlpHex(block.baseFeePerGas));
669
+ }
670
+ if (block.withdrawalsRoot) {
671
+ headerFields.push(block.withdrawalsRoot);
672
+ }
673
+ if (block.blobGasUsed !== undefined && block.blobGasUsed !== null) {
674
+ headerFields.push(toRlpHex(block.blobGasUsed));
675
+ }
676
+ if (block.excessBlobGas !== undefined && block.excessBlobGas !== null) {
677
+ headerFields.push(toRlpHex(block.excessBlobGas));
678
+ }
679
+ if (block.parentBeaconBlockRoot) {
680
+ headerFields.push(block.parentBeaconBlockRoot);
681
+ }
682
+ const blockAny = block;
683
+ if (blockAny.requestsHash) {
684
+ headerFields.push(blockAny.requestsHash);
685
+ }
686
+ const rlpEncoded = (0, _viem.toRlp)(headerFields);
687
+ // Verify the encoding produces the correct block hash
688
+ const computedHash = (0, _viem.keccak256)(rlpEncoded);
689
+ if (computedHash !== block.hash) {
690
+ throw new Error(`RLP encoding mismatch: computed hash ${computedHash} does not match block hash ${block.hash}`);
691
+ }
692
+ // Encode the Header struct: (uint64 height, bytes encodedHeader)
693
+ const clientMessage = (0, _viem.encodeAbiParameters)([{
694
+ type: "uint64",
695
+ name: "height"
696
+ }, {
697
+ type: "bytes",
698
+ name: "encodedHeader"
699
+ }], [block.number, rlpEncoded]);
700
+ const LIGHTCLIENT_ABI = [{
701
+ inputs: [{
702
+ name: "caller",
703
+ type: "address"
704
+ }, {
705
+ name: "clientId",
706
+ type: "uint32"
707
+ }, {
708
+ name: "clientMessage",
709
+ type: "bytes"
710
+ }, {
711
+ name: "relayer",
712
+ type: "address"
713
+ }],
714
+ name: "updateClient",
715
+ outputs: [],
716
+ stateMutability: "nonpayable",
717
+ type: "function"
718
+ }];
719
+ // Wait for the next block so the fetched block's hash is verifiable on-chain
720
+ let currentBlock = yield* (0, _effect.pipe)(_effect.Effect.tryPromise(() => publicClient.getBlockNumber()), _effect.Effect.retry(commonRetry));
721
+ while (currentBlock <= blockNumber) {
722
+ yield* _effect.Effect.sleep("1 second");
723
+ currentBlock = yield* _effect.Effect.tryPromise(() => publicClient.getBlockNumber());
724
+ }
725
+ const loopbackClient = yield* (0, _effect.pipe)(evm.readContract({
726
+ address: ibcHandlerAddress,
727
+ abi: _rpc.IBC_STORE_ABI,
728
+ functionName: "getClient",
729
+ args: [clientId]
730
+ }), _effect.Effect.retry(commonRetry));
731
+ // Submit the transaction
732
+ const txHash = yield* (0, _effect.pipe)(evm.writeContract({
733
+ address: loopbackClient,
734
+ abi: LIGHTCLIENT_ABI,
735
+ functionName: "updateClient",
736
+ args: [walletClient.account.address, clientId, clientMessage, walletClient.account.address],
737
+ chain: walletClient.chain,
738
+ account: walletClient.account
739
+ }), _effect.Effect.retry(commonRetry));
740
+ const chainId = yield* _effect.Effect.sync(() => this.config.destinationChainId);
741
+ return {
742
+ txHash,
743
+ blockNumber: block.number,
744
+ stateRoot: block.stateRoot,
745
+ chainId
746
+ };
747
+ }).pipe(_effect.Effect.provide(evm.PublicClient.Live({
748
+ chain: walletClient.chain,
749
+ transport: (0, _viem.http)(this.config.destinationRpcUrl)
750
+ })), _effect.Effect.provideService(evm.WalletClient, {
751
+ client: options.walletClient,
752
+ account: options.walletClient.account,
753
+ chain: options.walletClient.chain
754
+ }), _effect.Effect.runPromise);
755
+ }
756
+ /**
757
+ * Update loopback light client to a specific block height
758
+ *
759
+ * Fetches the IBC handler address internally from the destination ZAsset.
760
+ * The wallet client must be connected to the destination chain.
761
+ *
762
+ * @returns Transaction hash, block number, state root, and chain ID
763
+ */
764
+ async unsafeUpdateLightClient(options) {
765
+ const {
766
+ clientId,
767
+ height,
768
+ walletClient
769
+ } = options;
770
+ if (!walletClient.account) {
771
+ throw new Error("WalletClient must have an account");
772
+ }
773
+ if (!walletClient.chain) {
774
+ throw new Error("WalletClient must have a chain configured");
775
+ }
776
+ const publicClient = (0, _viem.createPublicClient)({
777
+ chain: walletClient.chain,
778
+ transport: (0, _viem.http)(this.config.destinationRpcUrl)
779
+ });
780
+ // Get IBC handler address from ZAsset
781
+ const ibcHandlerAddress = await this.dstClient.getIbcHandlerAddress(this.config.dstZAssetAddress);
782
+ // Get the block number
783
+ const blockNumber = height === "latest" ? await publicClient.getBlockNumber() : height;
784
+ // Get the block for metadata
785
+ const block = await publicClient.getBlock({
786
+ blockNumber
787
+ });
788
+ if (!block.number) {
789
+ throw new Error("Block number is null");
790
+ }
791
+ // Helper to convert bigint/number to minimal RLP hex encoding
792
+ const toRlpHex = value => {
793
+ if (value === undefined || value === null || value === 0n || value === 0) {
794
+ return "0x";
795
+ }
796
+ let hex = typeof value === "bigint" ? value.toString(16) : value.toString(16);
797
+ if (hex.length % 2 !== 0) {
798
+ hex = "0" + hex;
799
+ }
800
+ return `0x${hex}`;
801
+ };
802
+ // Build header fields in order (pre-merge + post-merge fields)
803
+ const headerFields = [block.parentHash, block.sha3Uncles, block.miner, block.stateRoot, block.transactionsRoot, block.receiptsRoot, block.logsBloom ?? "0x" + "00".repeat(256), toRlpHex(block.difficulty), toRlpHex(block.number), toRlpHex(block.gasLimit), toRlpHex(block.gasUsed), toRlpHex(block.timestamp), block.extraData, block.mixHash ?? "0x0000000000000000000000000000000000000000000000000000000000000000", block.nonce ?? "0x0000000000000000"];
804
+ // Post-merge fields
805
+ if (block.baseFeePerGas !== undefined && block.baseFeePerGas !== null) {
806
+ headerFields.push(toRlpHex(block.baseFeePerGas));
807
+ }
808
+ if (block.withdrawalsRoot) {
809
+ headerFields.push(block.withdrawalsRoot);
810
+ }
811
+ if (block.blobGasUsed !== undefined && block.blobGasUsed !== null) {
812
+ headerFields.push(toRlpHex(block.blobGasUsed));
813
+ }
814
+ if (block.excessBlobGas !== undefined && block.excessBlobGas !== null) {
815
+ headerFields.push(toRlpHex(block.excessBlobGas));
816
+ }
817
+ if (block.parentBeaconBlockRoot) {
818
+ headerFields.push(block.parentBeaconBlockRoot);
819
+ }
820
+ const blockAny = block;
821
+ if (blockAny.requestsHash) {
822
+ headerFields.push(blockAny.requestsHash);
823
+ }
824
+ const rlpEncoded = (0, _viem.toRlp)(headerFields);
825
+ // Verify the encoding produces the correct block hash
826
+ const computedHash = (0, _viem.keccak256)(rlpEncoded);
827
+ if (computedHash !== block.hash) {
828
+ throw new Error(`RLP encoding mismatch: computed hash ${computedHash} does not match block hash ${block.hash}`);
829
+ }
830
+ // Encode the Header struct: (uint64 height, bytes encodedHeader)
831
+ const clientMessage = (0, _viem.encodeAbiParameters)([{
832
+ type: "uint64",
833
+ name: "height"
834
+ }, {
835
+ type: "bytes",
836
+ name: "encodedHeader"
837
+ }], [block.number, rlpEncoded]);
838
+ const LIGHTCLIENT_ABI = [{
839
+ inputs: [{
840
+ name: "caller",
841
+ type: "address"
842
+ }, {
843
+ name: "clientId",
844
+ type: "uint32"
845
+ }, {
846
+ name: "clientMessage",
847
+ type: "bytes"
848
+ }, {
849
+ name: "relayer",
850
+ type: "address"
851
+ }],
852
+ name: "updateClient",
853
+ outputs: [],
854
+ stateMutability: "nonpayable",
855
+ type: "function"
856
+ }];
857
+ // Wait for the next block so the fetched block's hash is verifiable on-chain
858
+ let currentBlock = await publicClient.getBlockNumber();
859
+ while (currentBlock <= blockNumber) {
860
+ await new Promise(resolve => setTimeout(resolve, 1000));
861
+ currentBlock = await publicClient.getBlockNumber();
862
+ }
863
+ const loopbackClient = await publicClient.readContract({
864
+ address: ibcHandlerAddress,
865
+ abi: _rpc.IBC_STORE_ABI,
866
+ functionName: "getClient",
867
+ args: [clientId]
868
+ });
869
+ // Submit the transaction
870
+ const txHash = await walletClient.writeContractSync({
871
+ address: loopbackClient,
872
+ abi: LIGHTCLIENT_ABI,
873
+ functionName: "updateClient",
874
+ args: [walletClient.account.address, clientId, clientMessage, walletClient.account.address],
875
+ chain: walletClient.chain,
876
+ account: walletClient.account
877
+ }).then(x => x.transactionHash);
878
+ return {
879
+ txHash,
880
+ blockNumber: block.number,
881
+ stateRoot: block.stateRoot,
882
+ chainId: this.config.destinationChainId
883
+ };
884
+ }
885
+ /**
886
+ * Get redemption history for a secret
887
+ *
888
+ * Queries the Redeemed events filtered by the nullifier derived from the secret.
889
+ * This is a read-only operation that doesn't require a wallet.
890
+ *
891
+ * @param secret - The 32-byte secret as a hex string
892
+ * @param fromBlock - Start block number (default: earliest)
893
+ * @param toBlock - End block number (default: latest)
894
+ * @returns Array of redemption transactions
895
+ */
896
+ getRedemptionHistory(secret, fromBlock, toBlock) {
897
+ return _effect.Effect.gen(this, function* () {
898
+ const nullifier = this.getNullifier(secret);
899
+ return yield* (0, _effect.pipe)(_effect.Effect.tryPromise(() => this.dstClient.getRedemptionHistory(this.config.dstZAssetAddress, nullifier, fromBlock, toBlock)), _effect.Effect.retry(commonRetry));
900
+ }).pipe(_effect.Effect.runPromise);
901
+ }
902
+ /**
903
+ * Get redemption history for a secret
904
+ *
905
+ * Queries the Redeemed events filtered by the nullifier derived from the secret.
906
+ * This is a read-only operation that doesn't require a wallet.
907
+ *
908
+ * @param secret - The 32-byte secret as a hex string
909
+ * @param fromBlock - Start block number (default: earliest)
910
+ * @param toBlock - End block number (default: latest)
911
+ * @returns Array of redemption transactions
912
+ */
913
+ async unsafeGetRedemptionHistory(secret, fromBlock, toBlock) {
914
+ const nullifier = this.getNullifier(secret);
915
+ return this.dstClient.getRedemptionHistory(this.config.dstZAssetAddress, nullifier, fromBlock, toBlock);
916
+ }
917
+ /**
918
+ * Full redeem flow: generate proof + get attestation + submit transaction
919
+ *
920
+ * This method orchestrates the entire redemption process:
921
+ * 1. Generates a ZK proof via the prover server
922
+ * 2. Gets attestation from the attestation service
923
+ * 3. Submits the redeem transaction
924
+ *
925
+ * The wallet client must be connected to the destination chain.
926
+ *
927
+ * @returns Transaction hash, proof, and metadata
928
+ */
929
+ redeem(options) {
930
+ const {
931
+ paymentKey,
932
+ beneficiaries,
933
+ beneficiary,
934
+ amount,
935
+ clientIds,
936
+ selectedClientId,
937
+ walletClient,
938
+ unwrap = true
939
+ } = options;
940
+ // Resolve attestation URL and API key from options or stored config
941
+ const attestationUrl = this.config.attestorUrl;
942
+ const attestorApiKey = this.config.attestorApiKey;
943
+ if (!attestationUrl) {
944
+ throw Error("Attestation URL must be provided either in redeem options or ClientOptions");
945
+ }
946
+ if (!attestorApiKey) {
947
+ throw Error("Attestation API key must be provided either in redeem options or ClientOptions");
948
+ }
949
+ if (!walletClient.account) {
950
+ throw Error("WalletClient must have an account");
951
+ }
952
+ if (!walletClient.chain) {
953
+ throw Error("WalletClient must have a chain configured");
954
+ }
955
+ return _effect.Effect.gen(this, function* () {
956
+ // 1. Generate proof
957
+ const proofResult = yield* _effect.Effect.tryPromise({
958
+ try: () => this.generateProof(paymentKey, beneficiaries, beneficiary, amount, clientIds, selectedClientId),
959
+ catch: cause => _effect.Effect.fail(cause)
960
+ }).pipe(_effect.Effect.retry(commonRetry));
961
+ if (!proofResult.proof.success || !proofResult.proof.proofJson || !proofResult.metadata) {
962
+ return yield* _effect.Effect.fail(Error(proofResult.proof.error ?? "Proof generation failed"));
963
+ }
964
+ const proofJson = (0, _rpc.parseProofJson)(proofResult.proof.proofJson);
965
+ const metadata = proofResult.metadata;
966
+ const depositAddress = this.getDepositAddress(paymentKey, beneficiaries);
967
+ // 2. Get attestation
968
+ const attestationClient = new _attestation.AttestationClient(attestationUrl, attestorApiKey);
969
+ const attestationResponse = yield* _effect.Effect.tryPromise({
970
+ try: () => attestationClient.getAttestation(depositAddress, beneficiary),
971
+ catch: cause => _effect.Effect.fail(cause)
972
+ }).pipe(_effect.Effect.retry(commonRetry));
973
+ // 3. Build redeem params
974
+ const redeemParams = (0, _rpc.proofJsonToRedeemParams)(proofJson, {
975
+ lightClients: metadata.lightClients,
976
+ nullifier: metadata.nullifier,
977
+ value: metadata.value,
978
+ beneficiary: metadata.beneficiary,
979
+ attestedMessage: attestationResponse.attestedMessage,
980
+ signature: attestationResponse.signature
981
+ });
982
+ // 4. Submit transaction
983
+ const ZASSET_ABI = [{
984
+ inputs: [{
985
+ name: "proof",
986
+ type: "uint256[8]"
987
+ }, {
988
+ name: "commitments",
989
+ type: "uint256[2]"
990
+ }, {
991
+ name: "commitmentPok",
992
+ type: "uint256[2]"
993
+ }, {
994
+ name: "lightClients",
995
+ type: "tuple[]",
996
+ components: [{
997
+ name: "clientId",
998
+ type: "uint32"
999
+ }, {
1000
+ name: "height",
1001
+ type: "uint64"
1002
+ }]
1003
+ }, {
1004
+ name: "nullifier",
1005
+ type: "uint256"
1006
+ }, {
1007
+ name: "value",
1008
+ type: "uint256"
1009
+ }, {
1010
+ name: "beneficiary",
1011
+ type: "address"
1012
+ }, {
1013
+ name: "attestedMessage",
1014
+ type: "bytes32"
1015
+ }, {
1016
+ name: "signature",
1017
+ type: "bytes"
1018
+ }, {
1019
+ name: "unwrap",
1020
+ type: "bool"
1021
+ }],
1022
+ name: "redeem",
1023
+ outputs: [],
1024
+ stateMutability: "nonpayable",
1025
+ type: "function"
1026
+ }];
1027
+ const txHash = yield* (0, _effect.pipe)(evm.writeContract({
1028
+ address: this.config.dstZAssetAddress,
1029
+ abi: ZASSET_ABI,
1030
+ functionName: "redeem",
1031
+ args: [redeemParams.proof, redeemParams.commitments, redeemParams.commitmentPok, redeemParams.lightClients, redeemParams.nullifier, redeemParams.value, redeemParams.beneficiary, redeemParams.attestedMessage, redeemParams.signature, unwrap],
1032
+ chain: walletClient.chain,
1033
+ account: walletClient.account
1034
+ }), _effect.Effect.retry(commonRetry));
1035
+ return {
1036
+ txHash,
1037
+ proof: proofJson,
1038
+ metadata
1039
+ };
1040
+ }).pipe(_effect.Effect.provide(evm.PublicClient.Live({
1041
+ chain: options.walletClient.chain,
1042
+ transport: (0, _viem.http)(this.config.destinationRpcUrl)
1043
+ })), _effect.Effect.provideService(evm.WalletClient, {
1044
+ client: options.walletClient,
1045
+ account: options.walletClient.account,
1046
+ chain: options.walletClient.chain
1047
+ }), _effect.Effect.runPromise);
1048
+ }
1049
+ /**
1050
+ * Full redeem flow: generate proof + get attestation + submit transaction
1051
+ *
1052
+ * This method orchestrates the entire redemption process:
1053
+ * 1. Generates a ZK proof via the prover server
1054
+ * 2. Gets attestation from the attestation service
1055
+ * 3. Submits the redeem transaction
1056
+ *
1057
+ * The wallet client must be connected to the destination chain.
1058
+ *
1059
+ * @returns Transaction hash, proof, and metadata
1060
+ */
1061
+ async unsafeRedeem(options) {
1062
+ const {
1063
+ paymentKey,
1064
+ beneficiaries,
1065
+ beneficiary,
1066
+ amount,
1067
+ clientIds,
1068
+ selectedClientId,
1069
+ walletClient,
1070
+ unwrap = true
1071
+ } = options;
1072
+ // Resolve attestation URL and API key from options or stored config
1073
+ const attestationUrl = this.config.attestorUrl;
1074
+ const attestorApiKey = this.config.attestorApiKey;
1075
+ if (!attestationUrl) {
1076
+ throw new Error("Attestation URL must be provided either in redeem options or ClientOptions");
1077
+ }
1078
+ if (!attestorApiKey) {
1079
+ throw new Error("Attestation API key must be provided either in redeem options or ClientOptions");
1080
+ }
1081
+ if (!walletClient.account) {
1082
+ throw new Error("WalletClient must have an account");
1083
+ }
1084
+ if (!walletClient.chain) {
1085
+ throw new Error("WalletClient must have a chain configured");
1086
+ }
1087
+ // 1. Generate proof
1088
+ const proofResult = await this.generateProof(paymentKey, beneficiaries, beneficiary, amount, clientIds, selectedClientId);
1089
+ if (!proofResult.proof.success || !proofResult.proof.proofJson || !proofResult.metadata) {
1090
+ throw new Error(proofResult.proof.error ?? "Proof generation failed");
1091
+ }
1092
+ const proofJson = (0, _rpc.parseProofJson)(proofResult.proof.proofJson);
1093
+ const metadata = proofResult.metadata;
1094
+ const depositAddress = this.getDepositAddress(paymentKey, beneficiaries);
1095
+ // 2. Get attestation
1096
+ const attestationClient = new _attestation.AttestationClient(attestationUrl, attestorApiKey);
1097
+ const attestationResponse = await attestationClient.getAttestation(depositAddress, beneficiary);
1098
+ // 3. Build redeem params
1099
+ const redeemParams = (0, _rpc.proofJsonToRedeemParams)(proofJson, {
1100
+ lightClients: metadata.lightClients,
1101
+ nullifier: metadata.nullifier,
1102
+ value: metadata.value,
1103
+ beneficiary: metadata.beneficiary,
1104
+ attestedMessage: attestationResponse.attestedMessage,
1105
+ signature: attestationResponse.signature
1106
+ });
1107
+ // 4. Submit transaction
1108
+ const publicClient = (0, _viem.createPublicClient)({
1109
+ chain: walletClient.chain,
1110
+ transport: (0, _viem.http)(this.config.destinationRpcUrl)
1111
+ });
1112
+ const ZASSET_ABI = [{
1113
+ inputs: [{
1114
+ name: "proof",
1115
+ type: "uint256[8]"
1116
+ }, {
1117
+ name: "commitments",
1118
+ type: "uint256[2]"
1119
+ }, {
1120
+ name: "commitmentPok",
1121
+ type: "uint256[2]"
1122
+ }, {
1123
+ name: "lightClients",
1124
+ type: "tuple[]",
1125
+ components: [{
1126
+ name: "clientId",
1127
+ type: "uint32"
1128
+ }, {
1129
+ name: "height",
1130
+ type: "uint64"
1131
+ }]
1132
+ }, {
1133
+ name: "nullifier",
1134
+ type: "uint256"
1135
+ }, {
1136
+ name: "value",
1137
+ type: "uint256"
1138
+ }, {
1139
+ name: "beneficiary",
1140
+ type: "address"
1141
+ }, {
1142
+ name: "attestedMessage",
1143
+ type: "bytes32"
1144
+ }, {
1145
+ name: "signature",
1146
+ type: "bytes"
1147
+ }, {
1148
+ name: "unwrap",
1149
+ type: "bool"
1150
+ }],
1151
+ name: "redeem",
1152
+ outputs: [],
1153
+ stateMutability: "nonpayable",
1154
+ type: "function"
1155
+ }];
1156
+ const txHash = await walletClient.writeContractSync({
1157
+ address: this.config.dstZAssetAddress,
1158
+ abi: ZASSET_ABI,
1159
+ functionName: "redeem",
1160
+ args: [redeemParams.proof, redeemParams.commitments, redeemParams.commitmentPok, redeemParams.lightClients, redeemParams.nullifier, redeemParams.value, redeemParams.beneficiary, redeemParams.attestedMessage, redeemParams.signature, unwrap],
1161
+ chain: walletClient.chain,
1162
+ account: walletClient.account
1163
+ }).then(x => x.transactionHash);
1164
+ const receipt = await publicClient.waitForTransactionReceipt({
1165
+ hash: txHash
1166
+ });
1167
+ if (receipt.status === "reverted") {
1168
+ throw new Error(`Redeem transaction reverted: ${txHash}`);
1169
+ }
1170
+ return {
1171
+ txHash,
1172
+ proof: proofJson,
1173
+ metadata
1174
+ };
1175
+ }
1176
+ /**
1177
+ * Pad beneficiaries array to exactly 4 addresses
1178
+ * Empty array = unbounded mode (all zeros, any beneficiary allowed)
1179
+ */
1180
+ padBeneficiaries(beneficiaries) {
1181
+ if (beneficiaries.length > 4) {
1182
+ throw new Error("Maximum 4 beneficiaries allowed");
1183
+ }
1184
+ const padded = [beneficiaries[0] ?? ZERO_ADDRESS, beneficiaries[1] ?? ZERO_ADDRESS, beneficiaries[2] ?? ZERO_ADDRESS, beneficiaries[3] ?? ZERO_ADDRESS];
1185
+ return padded;
1186
+ }
1187
+ }
1188
+ /**
1189
+ * Wait for predicate on block height
1190
+ * @public
1191
+ */
1192
+ exports.UnionPrivatePayments = UnionPrivatePayments;
1193
+ const waitForBlockCondition = (publicClient, predicate, options) => {
1194
+ const timeoutMs = options?.timeoutMs ?? 60_000;
1195
+ return new Promise((resolve, reject) => {
1196
+ let done = false;
1197
+ const unwatch = publicClient.watchBlockNumber({
1198
+ onBlockNumber(blockNumber) {
1199
+ if (done) return;
1200
+ if (predicate(blockNumber)) {
1201
+ done = true;
1202
+ unwatch();
1203
+ resolve(blockNumber);
1204
+ }
1205
+ },
1206
+ onError(error) {
1207
+ if (done) return;
1208
+ done = true;
1209
+ unwatch();
1210
+ reject(error);
1211
+ }
1212
+ });
1213
+ setTimeout(() => {
1214
+ if (done) return;
1215
+ done = true;
1216
+ unwatch();
1217
+ reject(new Error("Timed out waiting for block condition"));
1218
+ }, timeoutMs);
1219
+ });
1220
+ };
1221
+ exports.waitForBlockCondition = waitForBlockCondition;
1222
+ //# sourceMappingURL=client.js.map