@veilo/sdk-core 0.4.0 → 0.6.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 (481) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +449 -1243
  3. package/accounts.d.ts +2 -0
  4. package/accounts.js +3 -0
  5. package/cloak.d.ts +2 -0
  6. package/cloak.js +3 -0
  7. package/config.d.ts +2 -2
  8. package/config.js +2 -3
  9. package/dist/cjs/accounts/admin.d.ts +84 -0
  10. package/dist/cjs/accounts/admin.js +208 -0
  11. package/dist/cjs/accounts/errors.d.ts +6 -0
  12. package/dist/cjs/accounts/errors.js +98 -0
  13. package/dist/cjs/accounts/index.d.ts +4 -0
  14. package/dist/cjs/accounts/index.js +20 -0
  15. package/dist/cjs/accounts/pdas.d.ts +23 -0
  16. package/dist/cjs/accounts/pdas.js +44 -0
  17. package/dist/cjs/accounts/queries.d.ts +41 -0
  18. package/dist/cjs/accounts/queries.js +95 -0
  19. package/dist/cjs/client.d.ts +2 -407
  20. package/dist/cjs/client.js +6 -938
  21. package/dist/cjs/cloak/client.d.ts +28 -0
  22. package/dist/cjs/cloak/client.js +68 -0
  23. package/dist/cjs/cloak/errors.d.ts +13 -0
  24. package/dist/cjs/cloak/errors.js +25 -0
  25. package/dist/cjs/cloak/helpers.d.ts +6 -0
  26. package/dist/cjs/cloak/helpers.js +35 -0
  27. package/dist/cjs/cloak/index.d.ts +6 -0
  28. package/dist/cjs/cloak/index.js +24 -0
  29. package/dist/cjs/cloak/polling.d.ts +7 -0
  30. package/dist/cjs/cloak/polling.js +66 -0
  31. package/dist/cjs/cloak/transport.d.ts +15 -0
  32. package/dist/cjs/cloak/transport.js +119 -0
  33. package/dist/cjs/cloak/types.d.ts +188 -0
  34. package/dist/cjs/cloak/types.js +5 -0
  35. package/dist/cjs/cloak.d.ts +1 -0
  36. package/dist/cjs/cloak.js +18 -0
  37. package/dist/cjs/compactNote.d.ts +21 -0
  38. package/dist/cjs/compactNote.js +31 -7
  39. package/dist/cjs/events/index.d.ts +6 -0
  40. package/dist/cjs/events/index.js +22 -0
  41. package/dist/cjs/events/parsing.d.ts +25 -0
  42. package/dist/cjs/events/parsing.js +158 -0
  43. package/dist/cjs/events/position.d.ts +26 -0
  44. package/dist/cjs/events/position.js +53 -0
  45. package/dist/cjs/events/recovery.d.ts +87 -0
  46. package/dist/cjs/events/recovery.js +281 -0
  47. package/dist/cjs/events/scanning.d.ts +35 -0
  48. package/dist/cjs/events/scanning.js +98 -0
  49. package/dist/cjs/events/tree.d.ts +27 -0
  50. package/dist/cjs/events/tree.js +63 -0
  51. package/dist/cjs/events/types.d.ts +39 -0
  52. package/dist/cjs/events.d.ts +1 -77
  53. package/dist/cjs/events.js +6 -154
  54. package/dist/cjs/identity/encoding.d.ts +9 -0
  55. package/dist/cjs/identity/encoding.js +85 -0
  56. package/dist/cjs/identity/index.d.ts +4 -0
  57. package/dist/cjs/identity/index.js +20 -0
  58. package/dist/cjs/identity/noteKey.d.ts +33 -0
  59. package/dist/cjs/identity/noteKey.js +97 -0
  60. package/dist/cjs/identity/spending.d.ts +18 -0
  61. package/dist/cjs/identity/spending.js +46 -0
  62. package/dist/cjs/identity/viewKey.d.ts +38 -0
  63. package/dist/cjs/identity/viewKey.js +105 -0
  64. package/dist/cjs/idl/index.d.ts +18 -0
  65. package/dist/cjs/idl/index.js +24 -0
  66. package/dist/cjs/idl/privacy_pool.json +9907 -9907
  67. package/dist/cjs/idl/privacy_pool_legacy.js +3307 -0
  68. package/dist/cjs/idl/privacy_pool_legacy.json +2302 -0
  69. package/dist/cjs/idl/privacy_pool_legacy2.d.ts +5 -0
  70. package/dist/cjs/idl/privacy_pool_legacy2.js +3397 -0
  71. package/dist/cjs/idl/privacy_pool_legacy2.json +2376 -0
  72. package/dist/cjs/index.d.ts +9 -3
  73. package/dist/cjs/index.js +15 -2
  74. package/dist/cjs/notes/amount.d.ts +2 -0
  75. package/dist/cjs/notes/amount.js +21 -0
  76. package/dist/cjs/notes/encryption.d.ts +41 -0
  77. package/dist/cjs/notes/encryption.js +75 -0
  78. package/dist/cjs/notes/index.d.ts +8 -0
  79. package/dist/cjs/notes/index.js +24 -0
  80. package/dist/cjs/notes/mailbox.d.ts +70 -0
  81. package/dist/cjs/notes/mailbox.js +164 -0
  82. package/dist/cjs/notes/model.d.ts +91 -0
  83. package/dist/cjs/notes/model.js +109 -0
  84. package/dist/cjs/notes/nullifier.d.ts +27 -0
  85. package/dist/cjs/notes/nullifier.js +45 -0
  86. package/dist/cjs/notes/recovery.d.ts +20 -0
  87. package/dist/cjs/notes/recovery.js +48 -0
  88. package/dist/cjs/notes/selection.d.ts +77 -0
  89. package/dist/cjs/notes/selection.js +193 -0
  90. package/dist/cjs/notes/spent.d.ts +60 -0
  91. package/dist/cjs/notes/spent.js +101 -0
  92. package/dist/cjs/perps/constants.d.ts +16 -0
  93. package/dist/cjs/perps/constants.js +52 -0
  94. package/dist/cjs/perps/index.d.ts +5 -0
  95. package/dist/cjs/perps/index.js +21 -0
  96. package/dist/cjs/perps/keys.d.ts +16 -0
  97. package/dist/cjs/perps/keys.js +43 -0
  98. package/dist/cjs/perps/pdas.d.ts +29 -0
  99. package/dist/cjs/perps/pdas.js +55 -0
  100. package/dist/cjs/perps/relayer.d.ts +9 -0
  101. package/dist/cjs/perps/relayer.js +35 -0
  102. package/dist/cjs/perps/types.d.ts +126 -0
  103. package/dist/cjs/perps/types.js +2 -0
  104. package/dist/cjs/positions/index.d.ts +4 -0
  105. package/dist/cjs/positions/index.js +20 -0
  106. package/dist/cjs/positions/keys.d.ts +29 -0
  107. package/dist/cjs/positions/keys.js +71 -0
  108. package/dist/cjs/positions/pdas.d.ts +15 -0
  109. package/dist/cjs/positions/pdas.js +54 -0
  110. package/dist/cjs/positions/relayer.d.ts +4 -0
  111. package/dist/cjs/positions/relayer.js +15 -0
  112. package/dist/cjs/positions/types.d.ts +97 -0
  113. package/dist/cjs/positions/types.js +2 -0
  114. package/dist/cjs/predictions/client.d.ts +41 -0
  115. package/dist/cjs/predictions/client.js +147 -0
  116. package/dist/cjs/predictions/index.d.ts +5 -0
  117. package/dist/cjs/predictions/index.js +21 -0
  118. package/dist/cjs/predictions/keys.d.ts +14 -0
  119. package/dist/cjs/predictions/keys.js +40 -0
  120. package/dist/cjs/predictions/pdas.d.ts +6 -0
  121. package/dist/cjs/predictions/pdas.js +13 -0
  122. package/dist/cjs/predictions/relayer.d.ts +3 -0
  123. package/dist/cjs/predictions/relayer.js +11 -0
  124. package/dist/cjs/predictions/types.d.ts +178 -0
  125. package/dist/cjs/predictions/types.js +2 -0
  126. package/dist/cjs/program.d.ts +2 -0
  127. package/dist/cjs/program.js +8 -7
  128. package/dist/cjs/proof.d.ts +1 -183
  129. package/dist/cjs/proof.js +16 -290
  130. package/dist/cjs/proofs/encoding.d.ts +17 -0
  131. package/dist/cjs/proofs/encoding.js +72 -0
  132. package/dist/cjs/proofs/formatting.d.ts +6 -0
  133. package/dist/cjs/proofs/formatting.js +34 -0
  134. package/dist/cjs/proofs/index.d.ts +5 -0
  135. package/dist/cjs/proofs/index.js +21 -0
  136. package/dist/cjs/proofs/swap.d.ts +87 -0
  137. package/dist/cjs/proofs/swap.js +144 -0
  138. package/dist/cjs/proofs/transaction.d.ts +28 -0
  139. package/dist/cjs/proofs/transaction.js +110 -0
  140. package/dist/cjs/proofs/types.d.ts +70 -0
  141. package/dist/cjs/proofs/types.js +2 -0
  142. package/dist/cjs/prover.d.ts +30 -4
  143. package/dist/cjs/prover.js +118 -49
  144. package/dist/cjs/relayer/api.d.ts +31 -0
  145. package/dist/cjs/relayer/api.js +86 -0
  146. package/dist/cjs/relayer/client.d.ts +73 -0
  147. package/dist/cjs/relayer/client.js +206 -0
  148. package/dist/cjs/relayer/crypto.d.ts +5 -0
  149. package/dist/cjs/relayer/crypto.js +26 -0
  150. package/dist/cjs/relayer/encoding.d.ts +2 -0
  151. package/dist/cjs/relayer/encoding.js +23 -0
  152. package/dist/cjs/relayer/errors.d.ts +7 -0
  153. package/dist/cjs/relayer/errors.js +17 -0
  154. package/dist/cjs/relayer/index.d.ts +6 -0
  155. package/dist/cjs/relayer/index.js +19 -0
  156. package/dist/cjs/relayer/internal-config.d.ts +36 -0
  157. package/dist/cjs/relayer/internal-config.js +9 -0
  158. package/dist/cjs/relayer/internal.d.ts +6 -0
  159. package/dist/cjs/relayer/internal.js +14 -0
  160. package/dist/cjs/relayer/transport.d.ts +19 -0
  161. package/dist/cjs/relayer/transport.js +68 -0
  162. package/dist/{src/relayer.d.ts → cjs/relayer/types.d.ts} +53 -96
  163. package/dist/cjs/relayer/types.js +5 -0
  164. package/dist/cjs/relayer.d.ts +1 -318
  165. package/dist/cjs/relayer.js +15 -254
  166. package/dist/cjs/shield/alt.js +8 -8
  167. package/dist/cjs/shield/errors.js +2 -2
  168. package/dist/cjs/shield/finalize.js +2 -2
  169. package/dist/cjs/shield/ix.d.ts +1 -1
  170. package/dist/cjs/shield/owner.js +9 -11
  171. package/dist/cjs/shield/ports.js +3 -3
  172. package/dist/cjs/shield/preflight.js +3 -3
  173. package/dist/cjs/shield/shield.js +20 -19
  174. package/dist/cjs/shield/types.d.ts +1 -1
  175. package/dist/cjs/transactions/deposit.d.ts +94 -0
  176. package/dist/cjs/transactions/deposit.js +234 -0
  177. package/dist/cjs/transactions/index.d.ts +7 -0
  178. package/dist/cjs/transactions/index.js +26 -0
  179. package/dist/cjs/transactions/swap.d.ts +71 -0
  180. package/dist/cjs/transactions/swap.js +184 -0
  181. package/dist/cjs/transactions/transact.d.ts +34 -0
  182. package/dist/cjs/transactions/transact.js +146 -0
  183. package/dist/cjs/transactions/transfer.d.ts +51 -0
  184. package/dist/cjs/transactions/transfer.js +106 -0
  185. package/dist/cjs/transactions/withdraw.d.ts +52 -0
  186. package/dist/cjs/transactions/withdraw.js +104 -0
  187. package/dist/cjs/utxo.d.ts +1 -235
  188. package/dist/cjs/utxo.js +15 -404
  189. package/dist/esm/accounts/admin.d.ts +84 -0
  190. package/dist/esm/accounts/admin.js +165 -0
  191. package/dist/esm/accounts/errors.d.ts +6 -0
  192. package/dist/esm/accounts/errors.js +95 -0
  193. package/dist/esm/accounts/index.d.ts +4 -0
  194. package/dist/esm/accounts/index.js +4 -0
  195. package/dist/esm/accounts/pdas.d.ts +23 -0
  196. package/dist/esm/accounts/pdas.js +38 -0
  197. package/dist/esm/accounts/queries.d.ts +41 -0
  198. package/dist/esm/accounts/queries.js +88 -0
  199. package/dist/esm/client.d.ts +2 -407
  200. package/dist/esm/client.js +3 -891
  201. package/dist/esm/cloak/client.d.ts +28 -0
  202. package/dist/esm/cloak/client.js +64 -0
  203. package/dist/esm/cloak/errors.d.ts +13 -0
  204. package/dist/esm/cloak/errors.js +21 -0
  205. package/dist/esm/cloak/helpers.d.ts +6 -0
  206. package/dist/esm/cloak/helpers.js +31 -0
  207. package/dist/esm/cloak/index.d.ts +6 -0
  208. package/dist/esm/cloak/index.js +6 -0
  209. package/dist/esm/cloak/polling.d.ts +7 -0
  210. package/dist/esm/cloak/polling.js +63 -0
  211. package/dist/esm/cloak/transport.d.ts +15 -0
  212. package/dist/esm/cloak/transport.js +115 -0
  213. package/dist/esm/cloak/types.d.ts +188 -0
  214. package/dist/esm/cloak/types.js +4 -0
  215. package/dist/esm/cloak.d.ts +1 -0
  216. package/dist/esm/cloak.js +2 -0
  217. package/dist/esm/compactNote.d.ts +21 -0
  218. package/dist/esm/compactNote.js +24 -1
  219. package/dist/esm/events/index.d.ts +6 -0
  220. package/dist/esm/events/index.js +6 -0
  221. package/dist/esm/events/parsing.d.ts +25 -0
  222. package/dist/esm/events/parsing.js +120 -0
  223. package/dist/esm/events/position.d.ts +26 -0
  224. package/dist/esm/events/position.js +48 -0
  225. package/dist/esm/events/recovery.d.ts +87 -0
  226. package/dist/esm/events/recovery.js +237 -0
  227. package/dist/esm/events/scanning.d.ts +35 -0
  228. package/dist/esm/events/scanning.js +92 -0
  229. package/dist/esm/events/tree.d.ts +27 -0
  230. package/dist/esm/events/tree.js +58 -0
  231. package/dist/esm/events/types.d.ts +39 -0
  232. package/dist/esm/events/types.js +1 -0
  233. package/dist/esm/events.d.ts +1 -77
  234. package/dist/esm/events.js +3 -129
  235. package/dist/esm/identity/encoding.d.ts +9 -0
  236. package/dist/esm/identity/encoding.js +75 -0
  237. package/dist/esm/identity/index.d.ts +4 -0
  238. package/dist/esm/identity/index.js +4 -0
  239. package/dist/esm/identity/noteKey.d.ts +33 -0
  240. package/dist/esm/identity/noteKey.js +91 -0
  241. package/dist/esm/identity/spending.d.ts +18 -0
  242. package/dist/esm/identity/spending.js +35 -0
  243. package/dist/esm/identity/viewKey.d.ts +38 -0
  244. package/dist/esm/identity/viewKey.js +96 -0
  245. package/dist/esm/idl/index.d.ts +18 -0
  246. package/dist/esm/idl/index.js +18 -0
  247. package/dist/esm/idl/privacy_pool.json +9907 -9907
  248. package/dist/esm/idl/privacy_pool_legacy.d.ts +5 -0
  249. package/dist/esm/idl/privacy_pool_legacy.js +3305 -0
  250. package/dist/esm/idl/privacy_pool_legacy.json +2302 -0
  251. package/dist/esm/idl/privacy_pool_legacy2.d.ts +5 -0
  252. package/dist/esm/idl/privacy_pool_legacy2.js +3395 -0
  253. package/dist/esm/idl/privacy_pool_legacy2.json +2376 -0
  254. package/dist/esm/index.d.ts +9 -3
  255. package/dist/esm/index.js +10 -3
  256. package/dist/esm/notes/amount.d.ts +2 -0
  257. package/dist/esm/notes/amount.js +18 -0
  258. package/dist/esm/notes/encryption.d.ts +41 -0
  259. package/dist/esm/notes/encryption.js +67 -0
  260. package/dist/esm/notes/index.d.ts +8 -0
  261. package/dist/esm/notes/index.js +8 -0
  262. package/dist/esm/notes/mailbox.d.ts +70 -0
  263. package/dist/esm/notes/mailbox.js +154 -0
  264. package/dist/esm/notes/model.d.ts +91 -0
  265. package/dist/esm/notes/model.js +99 -0
  266. package/dist/esm/notes/nullifier.d.ts +27 -0
  267. package/dist/esm/notes/nullifier.js +40 -0
  268. package/dist/esm/notes/recovery.d.ts +20 -0
  269. package/dist/esm/notes/recovery.js +45 -0
  270. package/dist/esm/notes/selection.d.ts +77 -0
  271. package/dist/esm/notes/selection.js +188 -0
  272. package/dist/esm/notes/spent.d.ts +60 -0
  273. package/dist/esm/notes/spent.js +96 -0
  274. package/dist/esm/perps/constants.d.ts +16 -0
  275. package/dist/esm/perps/constants.js +48 -0
  276. package/dist/esm/perps/index.d.ts +5 -0
  277. package/dist/esm/perps/index.js +5 -0
  278. package/dist/esm/perps/keys.d.ts +16 -0
  279. package/dist/esm/perps/keys.js +35 -0
  280. package/dist/esm/perps/pdas.d.ts +29 -0
  281. package/dist/esm/perps/pdas.js +47 -0
  282. package/dist/esm/perps/relayer.d.ts +9 -0
  283. package/dist/esm/perps/relayer.js +25 -0
  284. package/dist/esm/perps/types.d.ts +126 -0
  285. package/dist/esm/perps/types.js +1 -0
  286. package/dist/esm/positions/index.d.ts +4 -0
  287. package/dist/esm/positions/index.js +4 -0
  288. package/dist/esm/positions/keys.d.ts +29 -0
  289. package/dist/esm/positions/keys.js +65 -0
  290. package/dist/esm/positions/pdas.d.ts +15 -0
  291. package/dist/esm/positions/pdas.js +44 -0
  292. package/dist/esm/positions/relayer.d.ts +4 -0
  293. package/dist/esm/positions/relayer.js +10 -0
  294. package/dist/esm/positions/types.d.ts +97 -0
  295. package/dist/esm/positions/types.js +1 -0
  296. package/dist/esm/predictions/client.d.ts +41 -0
  297. package/dist/esm/predictions/client.js +141 -0
  298. package/dist/esm/predictions/index.d.ts +5 -0
  299. package/dist/esm/predictions/index.js +5 -0
  300. package/dist/esm/predictions/keys.d.ts +14 -0
  301. package/dist/esm/predictions/keys.js +33 -0
  302. package/dist/esm/predictions/pdas.d.ts +6 -0
  303. package/dist/esm/predictions/pdas.js +10 -0
  304. package/dist/esm/predictions/relayer.d.ts +3 -0
  305. package/dist/esm/predictions/relayer.js +7 -0
  306. package/dist/esm/predictions/types.d.ts +178 -0
  307. package/dist/esm/predictions/types.js +1 -0
  308. package/dist/esm/program.d.ts +2 -0
  309. package/dist/esm/program.js +4 -3
  310. package/dist/esm/proof.d.ts +1 -183
  311. package/dist/esm/proof.js +2 -281
  312. package/dist/esm/proofs/encoding.d.ts +17 -0
  313. package/dist/esm/proofs/encoding.js +68 -0
  314. package/dist/esm/proofs/formatting.d.ts +6 -0
  315. package/dist/esm/proofs/formatting.js +31 -0
  316. package/dist/esm/proofs/index.d.ts +5 -0
  317. package/dist/esm/proofs/index.js +5 -0
  318. package/dist/esm/proofs/swap.d.ts +87 -0
  319. package/dist/esm/proofs/swap.js +138 -0
  320. package/dist/esm/proofs/transaction.d.ts +28 -0
  321. package/dist/esm/proofs/transaction.js +105 -0
  322. package/dist/esm/proofs/types.d.ts +70 -0
  323. package/dist/esm/proofs/types.js +1 -0
  324. package/dist/esm/prover.d.ts +30 -4
  325. package/dist/esm/prover.js +115 -15
  326. package/dist/esm/relayer/api.d.ts +31 -0
  327. package/dist/esm/relayer/api.js +55 -0
  328. package/dist/esm/relayer/client.d.ts +73 -0
  329. package/dist/esm/relayer/client.js +199 -0
  330. package/dist/esm/relayer/crypto.d.ts +5 -0
  331. package/dist/esm/relayer/crypto.js +20 -0
  332. package/dist/esm/relayer/encoding.d.ts +2 -0
  333. package/dist/esm/relayer/encoding.js +19 -0
  334. package/dist/esm/relayer/errors.d.ts +7 -0
  335. package/dist/esm/relayer/errors.js +13 -0
  336. package/dist/esm/relayer/index.d.ts +6 -0
  337. package/dist/esm/relayer/index.js +3 -0
  338. package/dist/esm/relayer/internal-config.d.ts +36 -0
  339. package/dist/esm/relayer/internal-config.js +6 -0
  340. package/dist/esm/relayer/internal.d.ts +6 -0
  341. package/dist/esm/relayer/internal.js +10 -0
  342. package/dist/esm/relayer/transport.d.ts +19 -0
  343. package/dist/esm/relayer/transport.js +64 -0
  344. package/dist/esm/relayer/types.d.ts +275 -0
  345. package/dist/esm/relayer/types.js +4 -0
  346. package/dist/esm/relayer.d.ts +1 -318
  347. package/dist/esm/relayer.js +2 -249
  348. package/dist/esm/shield/alt.js +1 -1
  349. package/dist/esm/shield/errors.js +1 -1
  350. package/dist/esm/shield/finalize.js +1 -1
  351. package/dist/esm/shield/ix.d.ts +1 -1
  352. package/dist/esm/shield/owner.js +3 -5
  353. package/dist/esm/shield/ports.js +1 -1
  354. package/dist/esm/shield/preflight.js +1 -1
  355. package/dist/esm/shield/shield.js +4 -3
  356. package/dist/esm/shield/types.d.ts +1 -1
  357. package/dist/esm/transactions/deposit.d.ts +94 -0
  358. package/dist/esm/transactions/deposit.js +198 -0
  359. package/dist/esm/transactions/index.d.ts +7 -0
  360. package/dist/esm/transactions/index.js +7 -0
  361. package/dist/esm/transactions/swap.d.ts +71 -0
  362. package/dist/esm/transactions/swap.js +144 -0
  363. package/dist/esm/transactions/transact.d.ts +34 -0
  364. package/dist/esm/transactions/transact.js +110 -0
  365. package/dist/esm/transactions/transfer.d.ts +51 -0
  366. package/dist/esm/transactions/transfer.js +103 -0
  367. package/dist/esm/transactions/withdraw.d.ts +52 -0
  368. package/dist/esm/transactions/withdraw.js +101 -0
  369. package/dist/esm/utxo.d.ts +1 -235
  370. package/dist/esm/utxo.js +2 -382
  371. package/identity.d.ts +2 -0
  372. package/identity.js +3 -0
  373. package/idl.d.ts +2 -0
  374. package/idl.js +3 -0
  375. package/notes.d.ts +2 -0
  376. package/notes.js +3 -0
  377. package/package.json +131 -11
  378. package/perps.d.ts +2 -0
  379. package/perps.js +3 -0
  380. package/poseidon.d.ts +2 -2
  381. package/poseidon.js +2 -3
  382. package/positions.d.ts +2 -0
  383. package/positions.js +3 -0
  384. package/predictions.d.ts +2 -0
  385. package/predictions.js +3 -0
  386. package/proof.d.ts +2 -2
  387. package/proof.js +2 -3
  388. package/prover.d.ts +2 -2
  389. package/prover.js +2 -3
  390. package/relayer.d.ts +2 -0
  391. package/relayer.js +3 -0
  392. package/shield.d.ts +2 -2
  393. package/shield.js +2 -3
  394. package/transactions.d.ts +2 -0
  395. package/transactions.js +3 -0
  396. package/SHIELD_INTEGRATION.md +0 -143
  397. package/dist/src/client.d.ts +0 -407
  398. package/dist/src/client.js +0 -951
  399. package/dist/src/compactNote.d.ts +0 -107
  400. package/dist/src/compactNote.js +0 -167
  401. package/dist/src/config.d.ts +0 -82
  402. package/dist/src/config.js +0 -57
  403. package/dist/src/events.d.ts +0 -77
  404. package/dist/src/events.js +0 -167
  405. package/dist/src/idl/privacy_pool.js +0 -15218
  406. package/dist/src/index.d.ts +0 -16
  407. package/dist/src/index.js +0 -67
  408. package/dist/src/merkle.d.ts +0 -77
  409. package/dist/src/merkle.js +0 -156
  410. package/dist/src/poseidon.d.ts +0 -29
  411. package/dist/src/poseidon.js +0 -100
  412. package/dist/src/program.d.ts +0 -37
  413. package/dist/src/program.js +0 -61
  414. package/dist/src/proof.d.ts +0 -183
  415. package/dist/src/proof.js +0 -292
  416. package/dist/src/prover.d.ts +0 -54
  417. package/dist/src/prover.js +0 -112
  418. package/dist/src/random.d.ts +0 -16
  419. package/dist/src/random.js +0 -28
  420. package/dist/src/relayer.js +0 -257
  421. package/dist/src/retry.d.ts +0 -32
  422. package/dist/src/retry.js +0 -75
  423. package/dist/src/shield/alt.d.ts +0 -87
  424. package/dist/src/shield/alt.js +0 -194
  425. package/dist/src/shield/computeBudget.d.ts +0 -61
  426. package/dist/src/shield/computeBudget.js +0 -64
  427. package/dist/src/shield/errors.d.ts +0 -58
  428. package/dist/src/shield/errors.js +0 -121
  429. package/dist/src/shield/finalize.d.ts +0 -45
  430. package/dist/src/shield/finalize.js +0 -119
  431. package/dist/src/shield/index.d.ts +0 -35
  432. package/dist/src/shield/index.js +0 -68
  433. package/dist/src/shield/ix.d.ts +0 -54
  434. package/dist/src/shield/ix.js +0 -119
  435. package/dist/src/shield/owner.d.ts +0 -36
  436. package/dist/src/shield/owner.js +0 -126
  437. package/dist/src/shield/ports.d.ts +0 -43
  438. package/dist/src/shield/ports.js +0 -153
  439. package/dist/src/shield/preflight.d.ts +0 -30
  440. package/dist/src/shield/preflight.js +0 -154
  441. package/dist/src/shield/shield.d.ts +0 -68
  442. package/dist/src/shield/shield.js +0 -499
  443. package/dist/src/shield/types.d.ts +0 -202
  444. package/dist/src/utxo.d.ts +0 -235
  445. package/dist/src/utxo.js +0 -407
  446. package/dist/tests/compact-note.test.d.ts +0 -1
  447. package/dist/tests/compact-note.test.js +0 -173
  448. package/dist/tests/config.test.d.ts +0 -1
  449. package/dist/tests/config.test.js +0 -102
  450. package/dist/tests/edge-cases.test.d.ts +0 -1
  451. package/dist/tests/edge-cases.test.js +0 -220
  452. package/dist/tests/encryption.test.d.ts +0 -1
  453. package/dist/tests/encryption.test.js +0 -215
  454. package/dist/tests/events.test.d.ts +0 -1
  455. package/dist/tests/events.test.js +0 -78
  456. package/dist/tests/multi-tree.test.d.ts +0 -1
  457. package/dist/tests/multi-tree.test.js +0 -405
  458. package/dist/tests/pda.test.d.ts +0 -1
  459. package/dist/tests/pda.test.js +0 -229
  460. package/dist/tests/poseidon-builder-parity.test.d.ts +0 -1
  461. package/dist/tests/poseidon-builder-parity.test.js +0 -72
  462. package/dist/tests/poseidon.test.d.ts +0 -1
  463. package/dist/tests/poseidon.test.js +0 -142
  464. package/dist/tests/proof.test.d.ts +0 -1
  465. package/dist/tests/proof.test.js +0 -296
  466. package/dist/tests/relayer.test.d.ts +0 -1
  467. package/dist/tests/relayer.test.js +0 -271
  468. package/dist/tests/sdk.integration.test.d.ts +0 -1
  469. package/dist/tests/sdk.integration.test.js +0 -330
  470. package/dist/tests/shield-owner.test.d.ts +0 -1
  471. package/dist/tests/shield-owner.test.js +0 -89
  472. package/dist/tests/shield-preflight.test.d.ts +0 -1
  473. package/dist/tests/shield-preflight.test.js +0 -87
  474. package/dist/tests/shield-realproof.test.d.ts +0 -1
  475. package/dist/tests/shield-realproof.test.js +0 -272
  476. package/dist/tests/shield.test.d.ts +0 -1
  477. package/dist/tests/shield.test.js +0 -403
  478. package/dist/tests/utxo.test.d.ts +0 -1
  479. package/dist/tests/utxo.test.js +0 -140
  480. /package/dist/{src/shield → cjs/events}/types.js +0 -0
  481. /package/dist/{src/idl/privacy_pool.d.ts → cjs/idl/privacy_pool_legacy.d.ts} +0 -0
package/README.md CHANGED
@@ -1,1463 +1,669 @@
1
1
  # @veilo/sdk-core
2
2
 
3
- TypeScript SDK for the Veilo Privacy Pool Anchor program.
3
+ Build private payments and swaps on Solana with Veilo.
4
4
 
5
- This package provides a complete UTXO-based privacy protocol implementation on Solana with:
5
+ The SDK gives TypeScript applications a safe, typed way to:
6
6
 
7
- - **UTXO Model**: Full support for unspent transaction outputs with Poseidon commitments
8
- - **Multi-Tree Support**: Multiple concurrent Merkle trees for improved scalability
9
- - **ZK Proofs**: Integration with Circom circuits for private transactions
10
- - **Private Swaps**: Atomic cross-pool swaps via Jupiter (native SOL + SPL tokens)
11
- - **Note Encryption**: NaCl-based encrypted UTXO notes and blind mailbox delivery
12
- - **Event Scanning**: Reconstruct Merkle trees from on-chain events
13
- - **Poseidon Hashing**: BN254-curve compatible hashing using circomlibjs
14
- - **Relayer Support**: Built-in relayer infrastructure for private withdrawals and swaps
7
+ - shield SOL or SPL tokens into Veilo;
8
+ - withdraw, privately transfer, or privately swap shielded funds;
9
+ - open and manage private positions, Jupiter perps, and predictions;
10
+ - work with Veilo's relayer without handling its encryption protocol yourself;
11
+ - add partner-powered private sends and swaps through the Cloak API.
15
12
 
16
- > **Status:** Active development. The SDK supports full transaction privacy with ZK-SNARK proofs.
17
- > Proofs are generated off-chain and verified on-chain using Groth16.
13
+ It works with both ESM and CommonJS and includes TypeScript declarations.
18
14
 
19
- ---
15
+ > **Project status:** Active development. Test integrations on Devnet before using
16
+ > them with real funds.
20
17
 
21
- ## 1. Installation
18
+ ## Install
22
19
 
23
20
  ```bash
24
21
  npm install @veilo/sdk-core
25
22
  ```
26
23
 
27
- ---
28
-
29
- ## 2. Prerequisites
30
-
31
- - A running Solana validator (localnet/devnet/mainnet)
32
- - The `privacy-pool` program deployed to the network
33
- - A funded keypair
24
+ Install `snarkjs` only if your application generates proofs locally:
34
25
 
35
26
  ```bash
36
- export ANCHOR_PROVIDER_URL=https://api.devnet.solana.com
37
- export ANCHOR_WALLET=$HOME/.config/solana/id.json
27
+ npm install snarkjs
38
28
  ```
39
29
 
40
- ---
41
-
42
- ## 3. Build
43
-
44
- ```bash
45
- npm run build
46
- ```
30
+ You will also need:
47
31
 
48
- ---
32
+ - a Solana RPC connection;
33
+ - a connected wallet when a user must sign;
34
+ - the Veilo circuit `.wasm` and `.zkey` files for local proof generation;
35
+ - an API key only for partner services such as Cloak or Jupiter Predictions.
49
36
 
50
- ## 4. SDK API
37
+ ## Choose an integration
51
38
 
52
- ### 4.1 PDA Helpers
39
+ | What you want to build | Start with | Who signs? |
40
+ | --- | --- | --- |
41
+ | Let any wallet shield funds into Veilo | `shield()` | The user's wallet |
42
+ | Add private transfers or swaps to a partner app | `VeiloCloakClient` | The user's wallet |
43
+ | Build a full Veilo wallet experience | Managed relayer helpers | The relayer for private spends |
44
+ | Manage proofs, notes, trees, and transactions yourself | Transaction helpers | Your application or relayer |
53
45
 
54
- ```ts
55
- import {
56
- getPoolPdas,
57
- getNoteTreePda,
58
- getGlobalConfigPda,
59
- getNullifierMarkerPda,
60
- getSwapExecutorPda,
61
- } from "@veilo/sdk-core";
62
- import { PublicKey } from "@solana/web3.js";
63
-
64
- const programId = new PublicKey(
65
- "YourProgram1111111111111111111111111111111111",
66
- );
67
- const mintAddress = new PublicKey(
68
- "So11111111111111111111111111111111111111112",
69
- );
46
+ For most third-party deposit integrations, `shield()` is the best starting
47
+ point. For a managed private send or swap flow, use Cloak.
70
48
 
71
- // Pool PDAs (config, vault, nullifiers)
72
- const { config, vault, nullifiers } = getPoolPdas(programId, mintAddress);
49
+ ## Quick start: shield funds
73
50
 
74
- // Note tree PDA for tree ID 0
75
- const noteTree = getNoteTreePda(programId, mintAddress, 0);
76
-
77
- // Global config PDA (one per program)
78
- const globalConfig = getGlobalConfigPda(programId);
79
-
80
- // Nullifier marker PDA (prevents double-spend)
81
- const nullifier = new Uint8Array(32);
82
- const marker = getNullifierMarkerPda(programId, mintAddress, nullifier);
83
-
84
- // Swap executor PDA (for cross-pool swaps)
85
- const relayerPubkey = new PublicKey("...");
86
- const executor = getSwapExecutorPda(
87
- programId,
88
- sourceMint,
89
- destMint,
90
- inputNullifier0, // Uint8Array[32]
91
- relayerPubkey,
92
- );
93
- ```
94
-
95
- **PDA seeds (v3):**
96
-
97
- | Account | Seeds |
98
- | ---------------- | ------------------------------------------------------------------- |
99
- | Config | `["privacy_config_v3", mint]` |
100
- | Vault | `["privacy_vault_v3", mint]` |
101
- | Note Tree | `["privacy_note_tree_v3", mint, tree_id]` |
102
- | Nullifiers | `["privacy_nullifiers_v3", mint]` |
103
- | Nullifier Marker | `["nullifier_v3", mint, nullifier]` |
104
- | Global Config | `["global_config_v1"]` |
105
- | Swap Executor | `["swap_executor_v1", source_mint, dest_mint, nullifier0, relayer]` |
106
-
107
- ---
108
-
109
- ### 4.2 Pool Initialization
51
+ `shield()` creates an unsigned transaction. Your application asks the user's
52
+ wallet to sign it, submits it, and then finalizes the new private note.
110
53
 
111
54
  ```ts
55
+ import { Connection } from "@solana/web3.js";
112
56
  import {
113
- initializeGlobalConfig,
114
- initializePool,
115
- updatePoolConfig,
116
- addMerkleTree,
117
- getPoolConfig,
118
- updateGlobalConfig,
57
+ createTransactionProver,
58
+ finalizeShield,
59
+ resolveShieldOwner,
60
+ shield,
119
61
  } from "@veilo/sdk-core";
120
- import { NATIVE_SOL_MINT, sol } from "@veilo/sdk-core/config";
121
62
 
122
- // Initialize global config (once per program)
123
- await initializeGlobalConfig({ program, admin: adminKeypair });
63
+ const connection = new Connection(process.env.SOLANA_RPC_URL!, "confirmed");
124
64
 
125
- // Update global config
126
- await updateGlobalConfig({
127
- program,
128
- admin: adminKeypair,
129
- newAdmin: newAdminPubkey, // optional
130
- paused: false, // optional
131
- });
132
-
133
- // Initialize a pool for native SOL
134
- await initializePool({
135
- program,
136
- payer: adminKeypair,
137
- admin: adminKeypair,
138
- mintAddress: NATIVE_SOL_MINT,
139
- minDepositAmount: sol(0.1),
140
- maxDepositAmount: sol(100),
141
- minWithdrawAmount: sol(0.1),
142
- maxWithdrawAmount: sol(100),
143
- feeBps: 50, // 0.5%
144
- feeErrorMarginBps: 10, // 0.1% margin
145
- minWithdrawalFee: 1_000_000n,
146
- });
147
-
148
- // Add Merkle tree (tree ID 0)
149
- await addMerkleTree({
150
- program,
151
- payer: adminKeypair,
152
- mintAddress: NATIVE_SOL_MINT,
153
- treeId: 0,
154
- });
155
-
156
- // Update pool fee
157
- await updatePoolConfig({
158
- program,
159
- admin: adminKeypair,
160
- mintAddress: NATIVE_SOL_MINT,
161
- feeBps: 30,
65
+ // `wallet` is any connected Solana wallet with `publicKey` and
66
+ // `signTransaction` methods.
67
+ const owner = await resolveShieldOwner({ username: "alice" });
68
+ const prover = createTransactionProver({
69
+ wasmPath: "/circuits/transaction.wasm",
70
+ zkeyPath: "/circuits/transaction_final.zkey",
162
71
  });
163
72
 
164
- // Read pool configuration
165
- const poolConfig = await getPoolConfig(program, NATIVE_SOL_MINT);
166
- console.log("TVL:", poolConfig.totalTvl, " Fee:", poolConfig.feeBps, "bps");
167
- ```
168
-
169
- ---
170
-
171
- ### 4.3 On-Chain Account Queries
172
-
173
- ```ts
174
- import {
175
- fetchPoolConfig,
176
- checkNullifierSpent,
177
- getTreeInfo,
178
- getAllTreeInfo,
179
- getBestTreeForDeposit,
180
- } from "@veilo/sdk-core";
181
-
182
- // Fetch decoded PrivacyConfig account
183
- const config = await fetchPoolConfig(program, NATIVE_SOL_MINT);
184
-
185
- // Check if a nullifier has been spent
186
- const spent = await checkNullifierSpent(program, NATIVE_SOL_MINT, nullifier);
187
-
188
- // Info for a single tree
189
- const info = await getTreeInfo(program, NATIVE_SOL_MINT, 0);
190
- // info = { treeId, leafCount, root, isFull }
191
-
192
- // Info for all trees in a pool
193
- const allInfo = await getAllTreeInfo(program, NATIVE_SOL_MINT);
194
-
195
- // Pick the best tree for depositing (least full with capacity)
196
- const best = await getBestTreeForDeposit(program, NATIVE_SOL_MINT);
197
- // best = { treeId, leafCount, root }
198
- ```
199
-
200
- ---
201
-
202
- ### 4.4 UTXO Management
203
-
204
- ```ts
205
- import {
206
- generateKeypair,
207
- keypairFromPrivateKey,
208
- createUTXO,
209
- createOwnedUTXO,
210
- createOwnedZeroUTXO,
211
- deriveNullifier,
212
- type Keypair,
213
- type UTXO,
214
- type SerializedUTXO,
215
- type InputUTXO,
216
- } from "@veilo/sdk-core";
217
- import { NATIVE_SOL_MINT } from "@veilo/sdk-core/config";
218
- import { pubkeyToField } from "@veilo/sdk-core";
219
-
220
- // Generate a random UTXO keypair
221
- const keypair: Keypair = generateKeypair();
222
- // keypair = { privateKey: bigint, publicKey: bigint }
223
-
224
- // Restore from private key
225
- const restored = keypairFromPrivateKey(privateKeyBigInt);
226
-
227
- // Create an owned UTXO (includes private key)
228
- const ownedUtxo: SerializedUTXO = createOwnedUTXO({
229
- amount: 1_000_000_000n,
230
- privateKey: keypair.privateKey,
231
- mintAddress: NATIVE_SOL_MINT,
73
+ const result = await shield({
74
+ connection,
75
+ amount: 1_000_000_000n, // 1 SOL in lamports
76
+ owner,
77
+ signer: { publicKey: wallet.publicKey },
78
+ prover,
232
79
  });
233
80
 
234
- // Create a zero-value UTXO (for unused inputs/outputs)
235
- const zeroUtxo = createOwnedZeroUTXO(pubkeyToField(NATIVE_SOL_MINT), keypair);
236
-
237
- // Derive nullifier for spending
238
- const pathIndex = 0; // leaf index in Merkle tree
239
- const treeId = 0;
240
- const nullifier = deriveNullifier(
241
- ownedUtxo.privateKey,
242
- ownedUtxo.commitment,
243
- pathIndex,
244
- treeId,
245
- );
246
- ```
247
-
248
- **UTXO commitment:** `Poseidon(amount, pubkey, blinding, mintAddress)`
249
-
250
- **Nullifier:** `Poseidon(privateKey, commitment, pathIndex, treeId)`
251
-
252
- ---
253
-
254
- ### 4.5 UTXO Encryption
255
-
256
- The SDK provides NaCl-based encryption for UTXO notes (relayer storage) and blind mailbox delivery (wallet-to-wallet).
257
-
258
- ```ts
259
- import {
260
- deriveEncryptionKeypair,
261
- encryptUTXONote,
262
- decryptUTXONote,
263
- encryptBlindMailboxNote,
264
- decryptBlindMailboxNote,
265
- fetchAndDecryptNotes,
266
- computeSignature,
267
- inputUTXOToCircuitFormat,
268
- type EncryptedNote,
269
- type BlindMailboxNote,
270
- type BlindMailboxNoteData,
271
- type DecryptedNote,
272
- } from "@veilo/sdk-core";
273
- import { Keypair as SolanaKeypair } from "@solana/web3.js";
274
-
275
- // Derive a NaCl encryption keypair from a UTXO private key
276
- const encKeypair = deriveEncryptionKeypair(utxoKeypair.privateKey);
277
- // encKeypair = { publicKey: Uint8Array[32], secretKey: Uint8Array[32] }
278
-
279
- // Encrypt a UTXO note for relay storage
280
- const encryptedNote: EncryptedNote = encryptUTXONote(
281
- serializedUtxo, // SerializedUTXO
282
- encKeypair.publicKey, // NaCl public key (Uint8Array[32])
283
- );
284
-
285
- // Decrypt a UTXO note
286
- const decrypted: SerializedUTXO | null = decryptUTXONote(
287
- encryptedNote,
288
- encKeypair.secretKey, // NaCl secret key (Uint8Array[32])
289
- );
290
-
291
- // Blind mailbox: encrypt for a Solana wallet keypair
292
- const recipientKeypair = SolanaKeypair.generate();
293
-
294
- const mailboxNote: BlindMailboxNote = encryptBlindMailboxNote(
295
- serializedUtxo,
296
- recipientKeypair.publicKey.toBytes(), // ed25519 public key → X25519 DH
297
- );
81
+ const signed = await wallet.signTransaction(result.transaction);
82
+ const signature = await connection.sendRawTransaction(signed.serialize());
298
83
 
299
- // Recipient decrypts using their Solana secret key (64-byte)
300
- const mailboxDecrypted: DecryptedNote | null = decryptBlindMailboxNote(
301
- mailboxNote,
302
- recipientKeypair.secretKey, // 64-byte Solana secret key
84
+ const confirmation = await connection.confirmTransaction(
85
+ {
86
+ signature,
87
+ blockhash: result.blockhash,
88
+ lastValidBlockHeight: result.lastValidBlockHeight,
89
+ },
90
+ "confirmed",
303
91
  );
304
92
 
305
- // Compute UTXO signature (used in circuit)
306
- const sig = computeSignature(utxoKeypair.privateKey, utxo.commitment);
307
-
308
- // Format an InputUTXO for snarkjs circuit
309
- const circuitFormat = inputUTXOToCircuitFormat(inputUtxo);
310
- ```
311
-
312
- ---
313
-
314
- ### 4.6 Merkle Tree Operations
315
-
316
- ```ts
317
- import { MerkleTree } from "@veilo/sdk-core";
318
-
319
- // Create a new Merkle tree (default depth: 22)
320
- const tree = new MerkleTree();
321
-
322
- // Insert commitments
323
- const index = tree.insert(ownedUtxo.commitment);
324
-
325
- // Current root
326
- const root = tree.root();
327
-
328
- // Merkle path for proof generation
329
- const path = tree.path(index);
330
- // path = { pathElements: Uint8Array[], pathIndices: number[] }
331
-
332
- // Total leaves inserted
333
- const count = tree.totalLeaves;
334
- ```
335
-
336
- ---
337
-
338
- ### 4.7 Transaction Operations
339
-
340
- All transaction functions return `Promise<string>` (the transaction signature).
341
-
342
- #### Deposits
343
-
344
- ```ts
345
- import { deposit, type DepositResult } from "@veilo/sdk-core";
346
-
347
- const result: DepositResult = await deposit({
348
- program,
349
- depositor: depositorKeypair,
350
- mintAddress: NATIVE_SOL_MINT,
351
- amount: 1_000_000_000n, // 1 SOL
352
- recipientPubkey: pubkeyToField(depositorKeypair.publicKey), // bigint
353
- tree,
354
- proofBuilder,
355
- treeId: 0,
356
- });
357
- // result = { outputUTXOs, leafIndices, root }
358
- ```
359
-
360
- #### Withdrawals
361
-
362
- ```ts
363
- import { withdraw, type WithdrawResult } from "@veilo/sdk-core";
364
-
365
- const result: WithdrawResult = await withdraw({
366
- program,
367
- relayer: relayerKeypair,
368
- mintAddress: NATIVE_SOL_MINT,
369
- amount: 900_000_000n, // 0.9 SOL
370
- fee: 100_000_000n, // 0.1 SOL to relayer
371
- inputs: [inputUtxo1, zeroInputUtxo],
372
- outputs: [changeUtxo, zeroOutputUtxo],
373
- recipient: recipientKeypair.publicKey,
374
- tree,
375
- proofBuilder,
376
- treeId: 0,
377
- });
378
- ```
379
-
380
- #### Private Transfers
381
-
382
- ```ts
383
- import { privateTransfer, type TransferResult } from "@veilo/sdk-core";
93
+ if (confirmation.value.err) {
94
+ throw new Error("Shield transaction failed");
95
+ }
384
96
 
385
- const result: TransferResult = await privateTransfer({
386
- program,
387
- relayer: relayerKeypair,
388
- mintAddress: NATIVE_SOL_MINT,
389
- inputs: [inputUtxo1, zeroInputUtxo],
390
- outputs: [recipientUtxo, changeUtxo],
391
- recipient: relayerKeypair.publicKey,
392
- tree,
393
- proofBuilder,
394
- treeId: 0,
97
+ const finalized = await finalizeShield({
98
+ connection,
99
+ signature,
100
+ note: result.note,
101
+ owner,
395
102
  });
396
- ```
397
-
398
- #### Low-Level `transact`
399
-
400
- ```ts
401
- import { transact } from "@veilo/sdk-core";
402
103
 
403
- const signature: string = await transact({
404
- program,
405
- relayer: relayerKeypair,
406
- mintAddress: NATIVE_SOL_MINT,
407
- inputTreeId: 0,
408
- outputTreeId: 0,
409
- root: tree.root(),
410
- publicAmount: 0n,
411
- inputNullifiers: [nullifier1, nullifier2],
412
- outputCommitments: [output1.commitment, output2.commitment],
413
- extData: { recipient, relayer: relayerPubkey, fee: 0n, refund: 0n, claimant },
414
- proof,
415
- });
104
+ console.log("Private note created at leaf", finalized.leafIndex);
416
105
  ```
417
106
 
418
- ---
419
-
420
- #### Wallet-agnostic shielding
421
-
422
- `shield()` builds an unsigned v0 deposit transaction for any Solana wallet to
423
- sign. The signer funds the deposit, while the resulting private note can belong
424
- to a different Veilo user. The SDK never receives a wallet secret key and never
425
- broadcasts on the caller's behalf.
107
+ To shield an SPL token, pass its mint:
426
108
 
427
109
  ```ts
428
- import {
429
- createTransactionProver,
430
- resolveShieldOwner,
431
- shield,
432
- } from "@veilo/sdk-core";
433
-
434
- const owner = await resolveShieldOwner({ username: "alice" });
435
110
  const result = await shield({
436
111
  connection,
437
- amount: 5_000_000n,
438
- mint: USDC_MINT,
112
+ mint: usdcMint,
113
+ amount: 5_000_000n, // 5 USDC when the mint has 6 decimals
439
114
  owner,
440
115
  signer: { publicKey: wallet.publicKey },
441
- prover: createTransactionProver({ wasmPath, zkeyPath }),
116
+ prover,
442
117
  });
443
-
444
- const signed = await wallet.signTransaction(result.transaction);
445
- const signature = await connection.sendRawTransaction(signed.serialize());
446
118
  ```
447
119
 
448
- Use `rebuild()` if the blockhash or deadline expires, and call
449
- `finalizeShield()` after confirmation to obtain the authoritative Merkle leaf
450
- index. See [SHIELD_INTEGRATION.md](./SHIELD_INTEGRATION.md) for the complete
451
- build → sign → submit → finalize flow, retry rules, owner-key invariant, and
452
- fee/rent requirements.
453
-
454
- ---
120
+ Keep `result.note` private. It contains the information needed to recover the
121
+ shielded funds. `finalizeShield()` gives you the authoritative leaf index after
122
+ the transaction lands.
455
123
 
456
- ### 4.8 Private Swaps
457
-
458
- Cross-pool private swaps via Jupiter/Raydium. For native SOL source pools the SDK automatically composes the required `fund_native_source` + `transact_swap` instructions into a single atomic transaction.
124
+ If the blockhash expires before submission, reuse the proof with `rebuild()`:
459
125
 
460
126
  ```ts
461
- import {
462
- transactSwap,
463
- getSwapExecutorPda,
464
- fundNativeSource,
465
- type SwapParams,
466
- type SwapProofStruct,
467
- } from "@veilo/sdk-core";
127
+ import { rebuild } from "@veilo/sdk-core";
468
128
 
469
- // Execute a private swap (returns transaction signature)
470
- const signature: string = await transactSwap({
471
- program,
472
- relayer: relayerKeypair,
473
- sourceMint, // NATIVE_SOL_MINT or SPL token mint
474
- destMint,
475
- sourceRoot: tree.root(),
476
- sourceTreeId: 0,
477
- destTreeId: 0,
478
- inputNullifiers: [nullifier0, nullifier1],
479
- outputCommitments: [changeCommitment, destCommitment],
480
- proof, // SwapProofStruct
481
- swapParams: {
482
- minAmountOut: 950_000_000n,
483
- deadline: BigInt(Math.floor(Date.now() / 1000) + 60),
484
- sourceMint,
485
- destMint,
486
- destAmount: 950_000_000n,
487
- swapDataHash: new Uint8Array(32), // SHA-256 of DEX ix bytes, or zeros
488
- },
489
- swapAmount: 1_000_000_000n,
490
- swapData: jupiterInstructionBytes, // Buffer
491
- extData: { recipient, relayer: relayerPubkey, fee, refund: 0n, claimant },
492
- sourceVaultTokenAccount,
493
- sourceMintAccount,
494
- destVaultTokenAccount,
495
- destMintAccount,
496
- relayerTokenAccount,
497
- swapProgram: JUPITER_PROGRAM_ID,
498
- jupiterEventAuthority,
499
- });
500
-
501
- // Build the fund_native_source instruction standalone (advanced)
502
- const fundIx = await fundNativeSource({
503
- program,
504
- relayer: relayerKeypair,
505
- sourceMint: NATIVE_SOL_MINT,
506
- destMint,
507
- inputNullifier0: nullifier0,
508
- swapAmount: 1_000_000_000n,
509
- });
510
- // Returns TransactionInstruction — must be first ix in same tx as transact_swap
129
+ const refreshed = await rebuild(result, { connection });
511
130
  ```
512
131
 
513
- > **Note:** `transactSwap` handles the atomicity requirement automatically. Only use `fundNativeSource` directly if you are building transactions manually.
132
+ A stale Merkle root needs a new call to `shield()` because it requires a new
133
+ proof.
514
134
 
515
- ---
135
+ ## Cloak Partner API
516
136
 
517
- ### 4.9 Event Scanning & Tree Reconstruction
137
+ Cloak is the simplest route for partner applications that want a private send
138
+ or cross-asset private swap. The SDK handles request types, API authentication,
139
+ transaction decoding, polling, and structured errors. It never signs for the
140
+ user.
141
+
142
+ Keep your Cloak API key on a trusted server. Do not include it in a browser or
143
+ mobile bundle.
144
+
145
+ ### Create an order on your server
518
146
 
519
147
  ```ts
520
- import {
521
- scanCommitmentEvents,
522
- scanNullifierEvents,
523
- buildTreeFromEvents,
524
- type CommitmentEvent,
525
- type NullifierSpentEvent,
526
- } from "@veilo/sdk-core";
148
+ import { VeiloCloakClient } from "@veilo/sdk-core/cloak";
527
149
 
528
- // Scan all commitment events for a mint (paginated by signature)
529
- const { events, latestSignature } = await scanCommitmentEvents({
530
- program,
531
- mintAddress: NATIVE_SOL_MINT,
532
- treeId: 0,
533
- beforeSignature: undefined, // or last known signature for pagination
534
- limit: 1000,
150
+ const cloak = new VeiloCloakClient({
151
+ apiKey: process.env.VEILO_CLOAK_KEY!,
535
152
  });
536
- // events: CommitmentEvent[]
537
- // CommitmentEvent = { commitment, leafIndex, newRoot, timestamp, mintAddress, treeId }
538
153
 
539
- // Scan spent nullifier events
540
- const { events: nullEvents } = await scanNullifierEvents({
541
- program,
542
- mintAddress: NATIVE_SOL_MINT,
543
- beforeSignature: undefined,
544
- limit: 1000,
154
+ // The production API defaults to https://api.veilo.network/.
155
+ const { quote } = await cloak.getQuote({
156
+ amount: "100000000", // raw token units
157
+ sourceAssetId: "veilo-usdc",
158
+ destinationAssetId: "veilo-usdc",
159
+ senderAddress,
160
+ recipientAddress,
161
+ mode: "exact_in",
545
162
  });
546
- // NullifierSpentEvent = { nullifier, mintAddress, treeId }
547
163
 
548
- // Reconstruct a Merkle tree from on-chain events
549
- const {
550
- tree,
551
- events: allEvents,
552
- latestSignature: sig,
553
- } = await buildTreeFromEvents({
554
- program,
555
- mintAddress: NATIVE_SOL_MINT,
556
- treeId: 0,
557
- });
164
+ const { order } = await cloak.createOrder(
165
+ {
166
+ quote, // return the complete quote without changing it
167
+ senderAddress,
168
+ recipientAddress,
169
+ },
170
+ { idempotencyKey: crypto.randomUUID() },
171
+ );
558
172
  ```
559
173
 
560
- ---
174
+ For a cross-asset swap, use a different `destinationAssetId` and optionally add
175
+ `slippageBps` to the quote request. Use `listTokens()` to discover supported
176
+ asset IDs and their current limits.
561
177
 
562
- ### 4.10 Proof Generation
178
+ You can override the API address for another environment. Both the origin and
179
+ the full Cloak path are accepted:
563
180
 
564
181
  ```ts
565
- import {
566
- prepareTransactionInputs,
567
- formatInputsForSnarkjs,
568
- computeExtDataHash,
569
- encodeSnarkjsProofToTransactionProof,
570
- packProofToBytes,
571
- computeSwapParamsHash,
572
- computeSwapDataHash,
573
- type ExtData,
574
- type TransactionCircuitInputs,
575
- } from "@veilo/sdk-core";
576
-
577
- // Prepare inputs for the transaction circuit
578
- const circuitInputs: TransactionCircuitInputs = prepareTransactionInputs({
579
- root: tree.root(),
580
- publicAmount: 1_000_000_000n,
581
- extData: { recipient, relayer: relayerPubkey, fee: 0n, refund: 0n, claimant },
582
- mintAddress: NATIVE_SOL_MINT,
583
- inputs: [input1, input2],
584
- outputs: [output1, output2],
585
- inputTreeId: 0,
586
- outputTreeId: 0,
587
- });
588
-
589
- // Format for snarkjs (converts bigints / Uint8Arrays to strings)
590
- const snarkjsInputs = formatInputsForSnarkjs(circuitInputs);
591
-
592
- // After proof generation:
593
- // const { proof } = await snarkjs.groth16.fullProve(snarkjsInputs, wasmPath, zkeyPath);
594
- // const transactionProof = encodeSnarkjsProofToTransactionProof(proof);
595
-
596
- // Compute ext data hash (matches on-chain computation)
597
- const extDataHash = computeExtDataHash({
598
- recipient,
599
- relayer,
600
- fee: 0n,
601
- refund: 0n,
602
- claimant,
182
+ new VeiloCloakClient({
183
+ baseUrl: "https://api.veilo.network/", // `/cloak/v1` also works here
184
+ apiKey: process.env.VEILO_CLOAK_KEY!,
603
185
  });
604
-
605
- // Compute swap param/data hashes (for swap circuit inputs)
606
- const swapParamsHash = computeSwapParamsHash(swapParams);
607
- const swapDataHash = computeSwapDataHash(jupiterInstructionBytes);
608
186
  ```
609
187
 
610
- ---
188
+ ### Sign in the user's application
611
189
 
612
- ### 4.11 Fee Utilities
190
+ Send the returned `order` to the user's application, then deserialize and sign
191
+ its transaction:
613
192
 
614
193
  ```ts
615
- import {
616
- computeWithdrawalFee,
617
- computeSwapFee,
618
- DEFAULT_FEE_BPS,
619
- } from "@veilo/sdk-core/config";
194
+ import { deserializeCloakTransaction } from "@veilo/sdk-core/cloak";
620
195
 
621
- // Compute protocol fee for a withdrawal
622
- const fee = computeWithdrawalFee(amount, feeBps, minWithdrawalFee);
623
-
624
- // Compute protocol fee for a swap
625
- const swapFee = computeSwapFee(swapAmount, feeBps);
196
+ const transaction = deserializeCloakTransaction(order);
197
+ const signed = await wallet.signTransaction(transaction);
198
+ const signature = await connection.sendRawTransaction(signed.serialize());
199
+ await connection.confirmTransaction(signature, "confirmed");
626
200
  ```
627
201
 
628
- ---
629
-
630
- ### 4.12 Relayer & Admin Management
202
+ Send the signature back to your server. The deposit notification is optional,
203
+ but it can reduce processing latency:
631
204
 
632
205
  ```ts
633
- import { addRelayer, setPaused } from "@veilo/sdk-core";
634
-
635
- // Authorise a new relayer for a pool
636
- await addRelayer({
637
- program,
638
- admin: adminKeypair,
639
- mintAddress: NATIVE_SOL_MINT,
640
- newRelayer: relayerPubkey,
206
+ await cloak.notifyDeposit({
207
+ trackingId: order.trackingId,
208
+ txSignature: signature,
641
209
  });
642
210
 
643
- // Pause or unpause a pool
644
- await setPaused({
645
- program,
646
- admin: adminKeypair,
647
- mintAddress: NATIVE_SOL_MINT,
648
- paused: true,
211
+ const finalStatus = await cloak.waitForFinalStatus(order.trackingId, {
212
+ intervalMs: 3_000,
213
+ timeoutMs: 20 * 60_000,
649
214
  });
215
+
216
+ console.log(finalStatus.status);
650
217
  ```
651
218
 
652
- ---
219
+ If an unfunded order's transaction expires, call
220
+ `refreshTransaction(order.trackingId)` and ask the user to sign the refreshed
221
+ transaction.
653
222
 
654
- ### 4.13 Poseidon Utilities
223
+ ## Full private wallet flows
655
224
 
656
- ```ts
657
- import {
658
- initPoseidon,
659
- poseidon1,
660
- poseidon2,
661
- poseidon3,
662
- poseidon4,
663
- pubkeyToField,
664
- bytesToBigIntBE,
665
- bigIntToBytesBE,
666
- BN254_FR_MODULUS,
667
- } from "@veilo/sdk-core";
225
+ The SDK supports all Veilo privacy-pool operations. Pick the highest-level API
226
+ that fits your application:
668
227
 
669
- // Must be called once before using hash functions
670
- await initPoseidon();
671
-
672
- const h1 = poseidon1(12345n);
673
- const h2 = poseidon2(12345n, 67890n);
674
- const h3 = poseidon3(12345n, 67890n, 11111n);
675
- const h4 = poseidon4(12345n, 67890n, 11111n, 22222n);
228
+ | Operation | Managed relayer call | Direct SDK helper |
229
+ | --- | --- | --- |
230
+ | Deposit | Not required | `shield()` or `deposit()` |
231
+ | Withdraw | `submitWithdraw()` | `withdraw()` |
232
+ | Private transfer | `submitPrivateTransfer()` | `privateTransfer()` |
233
+ | Private swap | `submitPrivateSwap()` | `buildPrivateSwapInstructions()` or `transactSwap()` |
676
234
 
677
- // Convert a Solana PublicKey to a BN254 field element
678
- const field = pubkeyToField(NATIVE_SOL_MINT);
235
+ ### Use the managed relayer helpers
679
236
 
680
- // Byte bigint helpers (big-endian)
681
- const n = bytesToBigIntBE(bytes32);
682
- const b = bigIntToBytesBE(someField, 32);
683
- ```
684
-
685
- ---
686
-
687
- ### 4.14 Error Utilities
237
+ The SDK owns Veilo's production relayer URL, encryption key, request encryption,
238
+ and safe retry behavior. Applications call typed functions directly; there is
239
+ no relayer client or URL to configure.
688
240
 
689
241
  ```ts
690
- import { parseOnChainError } from "@veilo/sdk-core";
242
+ import {
243
+ submitWithdraw,
244
+ type WithdrawRequest,
245
+ } from "@veilo/sdk-core/relayer";
691
246
 
692
- try {
693
- await transactSwap({ ... });
694
- } catch (err) {
695
- // Returns a human-readable error string from Anchor/program errors
696
- const msg = parseOnChainError(err);
697
- console.error("Swap failed:", msg);
247
+ async function submitWithdrawal(request: WithdrawRequest) {
248
+ return submitWithdraw(request);
698
249
  }
699
250
  ```
700
251
 
701
- ---
702
-
703
- ## 5. Architecture
704
-
705
- ### Transaction Model
252
+ The same focused entry point provides account authentication, encrypted note
253
+ storage, Merkle tree reads, private transfers, private swaps, and these product
254
+ flows:
706
255
 
707
- Veilo uses a UTXO privacy model inspired by Zcash and Tornado Cash Nova:
256
+ | Product | Relayer helpers |
257
+ | --- | --- |
258
+ | Private positions | `submitOpenPosition()`, `submitClosePosition()`, `submitMergePositions()` |
259
+ | Jupiter perps | `submitJperpOpen()`, `submitJperpClose()`, TP/SL, cancellation, recovery, and reissue helpers |
260
+ | Jupiter predictions | `submitPredictionOpen()` and `submitPredictionReissue()` |
708
261
 
709
- - **Inputs**: 2 UTXOs (zero-value for deposits)
710
- - **Outputs**: 2 UTXOs (zero-value for withdrawals)
711
- - **Public Amount**: net pool change — positive = deposit, negative = withdrawal, zero = private transfer or swap
262
+ #### Submission always targets Veilo's relayer
712
263
 
713
- Each transaction consumes 2 input UTXOs (Merkle proofs), creates 2 output UTXOs (commitments inserted to tree), and generates 2 nullifiers to prevent double-spend.
264
+ Every helper above submits to Veilo's relayer. There is no `baseUrl` option, no
265
+ client to construct, and no supported way to redirect submission. That is
266
+ deliberate, for two independent reasons:
714
267
 
715
- ### Swap Architecture
268
+ 1. **The program requires it.** The privacy pool checks the submitting relayer
269
+ against an on-chain allowlist on every spend. Deposits (`public_amount > 0`)
270
+ are permissionless — which is why `shield()` and `deposit()` work with any
271
+ wallet — but withdrawals, transfers, swaps, positions, perps, and predictions
272
+ all fail with `RelayerNotAllowed` unless the transaction is signed by a
273
+ whitelisted relayer. Pointing the SDK at a different host would produce a
274
+ well-formed request that cannot land on chain.
275
+ 2. **These requests carry spending keys.** `TransactNote.privateKey`, and the
276
+ `claimantSecretKey` on position close and merge, *are* the spend authority for
277
+ the funds involved (see [A private note is valuable secret
278
+ data](#a-private-note-is-valuable-secret-data)). A configurable submission
279
+ target would be a configurable destination for user funds.
716
280
 
717
- Private swaps require two instructions in a **single atomic transaction**:
281
+ Running your own relayer is a whitelisting conversation rather than a
282
+ configuration flag — see [Support](#support). Reaching past the package's
283
+ `exports` map to import internal modules is unsupported and not covered by
284
+ semver.
718
285
 
719
- 1. `fund_native_source` pre-funds the swap executor with SOL from the vault (native SOL pools only)
720
- 2. `transact_swap` — verifies the ZK proof, spends input UTXOs, creates output UTXOs, and executes the DEX swap
721
-
722
- `transactSwap()` handles this automatically. The on-chain program validates atomicity via the instructions sysvar.
723
-
724
- ### Privacy Guarantees
725
-
726
- - **Commitment hiding**: amount, owner, blinding are hidden via Poseidon
727
- - **Nullifier uniqueness**: each UTXO can only be spent once
728
- - **Unlinkability**: no public link between inputs and outputs
729
- - **ZK proofs**: Groth16 verified on-chain
730
-
731
- ### Constants
732
-
733
- ```ts
734
- import {
735
- NATIVE_SOL_MINT, // PublicKey.default — native SOL pools
736
- MERKLE_TREE_DEPTH, // 22
737
- ROOT_HISTORY_SIZE, // 256
738
- DEFAULT_FEE_BPS, // 50 (0.5%)
739
- sol, // sol(1) === 1_000_000_000n
740
- } from "@veilo/sdk-core/config";
741
- ```
286
+ ### Spend status and private balance
742
287
 
743
- ### Type Exports
288
+ Nothing in a note says whether it has been spent — a note is yours until its
289
+ nullifier is published. So a balance is always two steps, and the SDK gives you
290
+ both:
744
291
 
745
292
  ```ts
746
- import type {
747
- // UTXO
748
- Keypair,
749
- UTXO,
750
- SerializedUTXO,
751
- InputUTXO,
752
- // Encryption
753
- EncryptedNote,
754
- BlindMailboxNote,
755
- BlindMailboxNoteData,
756
- DecryptedNote,
757
- // Proof
758
- ExtData,
759
- TransactionCircuitInputs,
760
- TransactionProofStruct,
761
- RawProof,
762
- TransactionProofBuilder,
763
- // Swap
764
- SwapProofStruct,
765
- SwapParams,
766
- // Tree / events
767
- MerklePath,
768
- CircuitMerklePath,
769
- TreeInfo,
770
- CommitmentEvent,
771
- NullifierSpentEvent,
772
- // Results
773
- DepositResult,
774
- WithdrawResult,
775
- TransferResult,
776
- // Config
777
- PoolInitConfig,
778
- PrivacyConfigAccount,
779
- GlobalConfigAccount,
780
- } from "@veilo/sdk-core";
781
- ```
293
+ import { getPrivateBalance, checkNullifiersSpent } from "@veilo/sdk-core";
782
294
 
783
- ---
784
-
785
- ## 6. Development
786
-
787
- ```bash
788
- # Run tests (requires devnet or local validator)
789
- npm test
295
+ const { total, byMint, unspent, spent } = await getPrivateBalance(myNotes);
790
296
  ```
791
297
 
792
- ---
793
-
794
- ## 7. Resources
795
-
796
- - **Repository**: https://github.com/VeiloSolana/veilo-sdk
797
- - **Circomlibjs**: https://github.com/iden3/circomlibjs
798
- - **Poseidon Hash**: https://www.poseidon-hash.info/
799
-
800
- ---
801
-
802
- ## License
298
+ Each note needs an `amount`, a 64-character hex `nullifier`, and optionally a
299
+ `mint` to group by. `getPrivateBalance` asks the relayer which nullifiers are
300
+ spent, then sums what is left; `unspent` and `spent` hand back your own note
301
+ objects, so you can render from them directly.
803
302
 
804
- ISC
303
+ `checkNullifiersSpent(nullifiers)` is the same question on its own. It
304
+ deduplicates, splits into the server's 200-per-request batches, issues them
305
+ concurrently, and returns a `Set` for membership testing. It also lower-cases
306
+ input: the endpoint validates case-insensitively but answers in lower case, so
307
+ upper-case hex would otherwise never match and every note would read as unspent.
805
308
 
806
- This package provides a complete UTXO-based privacy protocol implementation on Solana with:
309
+ To compute a balance without the relayer from a chain scan of nullifier
310
+ events, or a local cache — supply the answer yourself:
807
311
 
808
- - **UTXO Model**: Full support for unspent transaction outputs with Poseidon commitments
809
- - **Multi-Tree Support**: Multiple concurrent Merkle trees for improved scalability
810
- - **ZK Proofs**: Integration with Circom circuits for private transactions
811
- - **Flexible Operations**: Deposits, withdrawals, and private transfers
812
- - **Poseidon Hashing**: BN254-curve compatible hashing using circomlibjs
813
- - **Merkle Trees**: Off-chain Merkle tree management with proof generation
814
- - **Relayer Support**: Built-in relayer infrastructure for private withdrawals
815
-
816
- > **Status:** Active development. The SDK supports full transaction privacy with ZK-SNARK proofs.
817
- > Proofs are generated off-chain and verified on-chain using Groth16.
818
-
819
- ---
820
-
821
- ## 1. Installation
822
-
823
- ```bash
824
- npm install @veilo/sdk-core
825
- ```
826
-
827
- Or from source:
828
-
829
- ```bash
830
- cd core-sdk
831
- npm install
312
+ ```ts
313
+ await getPrivateBalance(myNotes, { resolveSpent: async (ns) => mySpentSet(ns) });
832
314
  ```
833
315
 
834
- ---
835
-
836
- ## 2. Prerequisites
316
+ Amounts stay `bigint` end to end. A `number` amount above `Number.MAX_SAFE_INTEGER`
317
+ is rejected rather than silently rounded, and a malformed nullifier throws
318
+ instead of counting as unspent — either would overstate a balance.
837
319
 
838
- You need:
320
+ ### Choosing notes to spend
839
321
 
840
- - A running Solana validator (localnet/devnet/mainnet):
322
+ Two rules govern this, and both are easy to get wrong:
841
323
 
842
- ```bash
843
- solana-test-validator
844
- ```
324
+ - the transaction circuit is **2-in-2-out**, so one transaction spends at most
325
+ two notes;
326
+ - notes are only co-spendable inside the **same Merkle tree**, and the tree is
327
+ derived from the mint.
845
328
 
846
- - The `privacy-pool` program deployed to the network
847
- - The `privacy-pool` Anchor IDL available:
848
-
849
- ```text
850
- idl/idl/privacy_pool.json
851
- ```
852
-
853
- - A funded keypair:
854
-
855
- ```bash
856
- solana config set --url http://127.0.0.1:8899
857
- solana-keygen new --outfile ~/.config/solana/id.json
858
- solana airdrop 10
859
- ```
860
-
861
- Environment variables:
329
+ ```ts
330
+ import { selectNotesForAmount, canonicalTreeId } from "@veilo/sdk-core";
862
331
 
863
- ```bash
864
- export ANCHOR_PROVIDER_URL=http://127.0.0.1:8899
865
- export ANCHOR_WALLET=$HOME/.config/solana/id.json
332
+ const selection = selectNotesForAmount(unspentNotes, amountRaw, { mint });
333
+ if (!selection.ok) throw new Error(selection.message); // NO_NOTES | INSUFFICIENT_FUNDS
334
+ if (selection.requiresMerge) {
335
+ // more than two inputs — combine them before proving
336
+ }
866
337
  ```
867
338
 
868
- ---
339
+ It searches each tree independently and returns the best result: the smallest
340
+ single note that covers the amount, else the pair with the least change (found
341
+ by a two-pointer scan, not an all-pairs search), else the largest notes greedily
342
+ with `requiresMerge` set. A failure reports `available`, the largest total
343
+ reachable within one tree.
869
344
 
870
- ## 3. Build
345
+ `canonicalTreeId(mint)` derives a note's tree the way the relayer does. **Derive
346
+ it; never trust a stored `treeId`.** Change notes are written with the on-chain
347
+ shard index while deposits and synced notes carry the mint-derived id — for
348
+ native SOL both are 0 so the difference hides, but for SPL tokens they diverge
349
+ and co-spending across the two fails at proof time as a commitment mismatch.
871
350
 
872
- ```bash
873
- npm run build
874
- ```
351
+ ### Private product keys and recovery
875
352
 
876
- ---
877
-
878
- ## 4. SDK API
879
-
880
- ### 4.1 PDA Helpers
353
+ Private positions, perps, and predictions use deterministic client-held keys.
354
+ The SDK provides the exact derivations used by Veilo's wallet, extension,
355
+ relayer, and program tests. Keep the spending key and claimant secret on the
356
+ user's device; send claimant secrets only inside the SDK's encrypted relayer
357
+ requests.
881
358
 
882
359
  ```ts
883
360
  import {
884
- getPoolPdas,
885
- getNoteTreePda,
886
- getGlobalConfigPda,
887
- getNullifierMarkerPda,
361
+ derivePositionKeyBundle,
362
+ deriveSpendingKeyWithSigner,
363
+ encodeClaimantSecretKey,
364
+ initPoseidon,
365
+ submitOpenPosition,
888
366
  } from "@veilo/sdk-core";
889
- import { PublicKey } from "@solana/web3.js";
890
367
 
891
- const programId = new PublicKey(
892
- "YourProgram1111111111111111111111111111111111",
368
+ await initPoseidon();
369
+ const spendingKey = await deriveSpendingKeyWithSigner(
370
+ (message) => wallet.signMessage(message),
893
371
  );
894
- const mintAddress = new PublicKey(
895
- "So11111111111111111111111111111111111111112",
896
- ); // Native SOL
897
-
898
- // Get pool PDAs
899
- const { config, vault, nullifiers } = getPoolPdas(programId, mintAddress);
900
-
901
- // Get note tree PDA for tree ID 0
902
- const noteTree = getNoteTreePda(programId, mintAddress, 0);
372
+ const positionKeys = derivePositionKeyBundle(spendingKey, nextPositionIndex);
903
373
 
904
- // Get global config
905
- const globalConfig = getGlobalConfigPda(programId);
374
+ await submitOpenPosition({
375
+ // Select private source notes in your wallet before calling the relayer.
376
+ notes,
377
+ sourceMintAddress,
378
+ destMintAddress,
379
+ swapAmountRaw,
380
+ slippageBps: 50,
381
+ userPublicKey: wallet.publicKey.toBase58(),
382
+ veiloPublicKey,
383
+ position: positionKeys.position,
384
+ });
906
385
 
907
- // Get nullifier marker PDA
908
- const nullifier = new Uint8Array(32);
909
- const marker = getNullifierMarkerPda(programId, mintAddress, 0, nullifier);
386
+ // Persist the returned position data and `nextPositionIndex`. Re-derive the
387
+ // same claimant later when closing or merging the position.
388
+ const claimantSecretKey = encodeClaimantSecretKey(positionKeys.claimant);
910
389
  ```
911
390
 
912
- **PDA seeds (v3):**
913
-
914
- - Config: `["privacy_config_v3", mint_address]`
915
- - Vault: `["privacy_vault_v3", mint_address]`
916
- - Note Tree: `["privacy_note_tree_v3", mint_address, tree_id]`
917
- - Nullifiers: `["privacy_nullifiers_v3", mint_address]`
918
- - Nullifier Marker: `["privacy_nullifier_v3", mint_address, tree_id, nullifier]`
919
- - Global Config: `["global_config_v1"]`
920
-
921
- ---
391
+ Use `deriveJperpKeyBundle()` and `getJperpMarketPayload()` for private perps.
392
+ Use `derivePredictionKeyBundle()` for private predictions. Lower-level key
393
+ derivations are also exported when an application needs them individually. The
394
+ PDA helpers in each focused entry point support on-chain recovery scans on a
395
+ fresh device.
922
396
 
923
- ### 4.2 Pool Initialization
397
+ Predictions have one additional step: Jupiter returns an unsigned order,
398
+ close, or claim transaction. The SDK exposes that API without taking custody
399
+ of signing:
924
400
 
925
401
  ```ts
926
- import * as anchor from "@coral-xyz/anchor";
927
402
  import {
928
- initializeGlobalConfig,
929
- initializePool,
930
- updatePoolConfig,
931
- addMerkleTree,
932
- getPoolConfig,
933
- } from "@veilo/sdk-core";
934
- import { NATIVE_SOL_MINT, sol } from "@veilo/sdk-core/config";
935
-
936
- // Initialize global config (once per program)
937
- await initializeGlobalConfig({
938
- program,
939
- admin: adminKeypair,
940
- });
403
+ JupiterPredictionClient,
404
+ deserializePredictionTransaction,
405
+ } from "@veilo/sdk-core/predictions";
941
406
 
942
- // Initialize a pool for native SOL
943
- await initializePool({
944
- program,
945
- payer: adminKeypair,
946
- admin: adminKeypair,
947
- mintAddress: NATIVE_SOL_MINT,
948
- minDepositAmount: sol(0.1), // 0.1 SOL
949
- maxDepositAmount: sol(100), // 100 SOL
950
- minWithdrawAmount: sol(0.1),
951
- maxWithdrawAmount: sol(100),
952
- feeBps: 50, // 0.5%
953
- feeErrorMarginBps: 10, // 0.1% margin
954
- minWithdrawalFee: 1_000_000n, // 0.001 SOL minimum
407
+ const predictions = new JupiterPredictionClient({ apiKey: jupiterApiKey });
408
+ const order = await predictions.placeOrder({
409
+ ownerPubkey: ephemeral.publicKey.toBase58(),
410
+ marketId,
411
+ isYes: true,
412
+ isBuy: true,
413
+ depositAmount: "5000000",
414
+ depositMint: usdcMint,
955
415
  });
956
-
957
- // Add first Merkle tree (tree ID 0)
958
- await addMerkleTree({
959
- program,
960
- payer: adminKeypair,
961
- mintAddress: NATIVE_SOL_MINT,
962
- treeId: 0,
963
- });
964
-
965
- // Update pool configuration
966
- await updatePoolConfig({
967
- program,
968
- admin: adminKeypair,
969
- mintAddress: NATIVE_SOL_MINT,
970
- feeBps: 30, // Change to 0.3%
971
- });
972
-
973
- // Read pool configuration
974
- const poolConfig = await getPoolConfig(program, NATIVE_SOL_MINT);
975
- console.log("TVL:", poolConfig.totalTvl);
976
- console.log("Fee:", poolConfig.feeBps, "bps");
977
- console.log("Num Trees:", poolConfig.numTrees);
416
+ const transaction = deserializePredictionTransaction(order);
417
+ // Ask the deterministic ephemeral wallet to sign, then submit and confirm it.
978
418
  ```
979
419
 
980
- ---
420
+ The SDK deliberately does not own application storage or choose which notes to
421
+ spend. Persist indexes and returned product records only after the corresponding
422
+ transaction is confirmed.
981
423
 
982
- ### 4.3 UTXO Management
424
+ ### Use the direct helpers
983
425
 
984
- The SDK uses a UTXO (Unspent Transaction Output) model with Poseidon commitments:
426
+ Direct helpers are intended for applications that already maintain Veilo note
427
+ and Merkle tree state and can generate proofs.
985
428
 
986
429
  ```ts
987
430
  import {
988
- generateKeypair,
989
- keypairFromPrivateKey,
990
- createUTXO,
991
- createOwnedUTXO,
992
- createOwnedZeroUTXO,
993
- deriveNullifier,
994
- type Keypair,
995
- type UTXO,
996
- type SerializedUTXO,
997
- type InputUTXO,
431
+ NATIVE_SOL_MINT,
432
+ createTransactionProver,
433
+ createVeiloProgram,
434
+ deposit,
998
435
  } from "@veilo/sdk-core";
999
- import { NATIVE_SOL_MINT } from "@veilo/sdk-core/config";
1000
- import { pubkeyToField } from "@veilo/sdk-core";
1001
-
1002
- // Generate a random keypair
1003
- const keypair: Keypair = generateKeypair();
1004
- // keypair = { privateKey: bigint, publicKey: bigint }
1005
436
 
1006
- // Restore keypair from private key
1007
- const restored = keypairFromPrivateKey(privateKeyBigInt);
437
+ const program = createVeiloProgram(connection, anchorWallet);
438
+ const proofBuilder = createTransactionProver({
439
+ wasmPath: "/circuits/transaction.wasm",
440
+ zkeyPath: "/circuits/transaction_final.zkey",
441
+ });
1008
442
 
1009
- // Create an owned UTXO (includes private key)
1010
- const ownedUtxo: SerializedUTXO = createOwnedUTXO({
1011
- amount: 1_000_000_000n,
1012
- privateKey: keypair.privateKey,
443
+ const built = await deposit({
444
+ program,
445
+ depositor: { publicKey: wallet.publicKey },
1013
446
  mintAddress: NATIVE_SOL_MINT,
447
+ amount: 1_000_000_000n,
448
+ recipientPubkey: veiloOwnerPublicKey,
449
+ noteRecipientWallet: wallet.publicKey,
450
+ tree,
451
+ proofBuilder,
452
+ treeId: 0,
1014
453
  });
1015
454
 
1016
- // Create a zero UTXO (for unused inputs/outputs)
1017
- const zeroUtxo = createOwnedZeroUTXO(pubkeyToField(NATIVE_SOL_MINT), keypair);
1018
-
1019
- // Derive nullifier for spending
1020
- const nullifier = deriveNullifier(
1021
- ownedUtxo.privateKey,
1022
- ownedUtxo.commitment,
1023
- 0, // pathIndex in Merkle tree
1024
- 0, // treeId
1025
- );
1026
- ```
1027
-
1028
- **UTXO commitment formula:**
1029
-
1030
- ```
1031
- commitment = Poseidon(amount, pubkey, blinding, mintAddress)
1032
- ```
1033
-
1034
- **Nullifier formula:**
455
+ const signed = await wallet.signTransaction(built.transaction);
456
+ const signature = await connection.sendRawTransaction(signed.serialize());
457
+ await connection.confirmTransaction(signature, "confirmed");
1035
458
 
459
+ // Update the local tree only after on-chain confirmation.
460
+ const receipt = built.commit();
1036
461
  ```
1037
- nullifier = Poseidon(privateKey, commitment, pathIndex, treeId)
1038
- ```
1039
-
1040
- ---
1041
462
 
1042
- ### 4.4 Merkle Tree Operations
463
+ `withdraw()` and `privateTransfer()` accept two spendable input notes, build the
464
+ proof, submit through the supplied relayer signer, and return the resulting
465
+ change or output notes. Important rules are enforced by the SDK:
1043
466
 
1044
- ```ts
1045
- import { MerkleTree } from "@veilo/sdk-core";
467
+ - withdrawal amounts must be positive and fit within the selected notes;
468
+ - private-transfer outputs must equal the total input amount;
469
+ - direct private transfers use a zero public fee;
470
+ - note-recipient wallet keys should be supplied so new notes remain recoverable.
1046
471
 
1047
- // Create a new Merkle tree (default depth: 20)
1048
- const tree = new MerkleTree();
1049
-
1050
- // Insert commitments
1051
- const index1 = tree.insert(ownedUtxo1.commitment);
1052
- const index2 = tree.insert(ownedUtxo2.commitment);
1053
-
1054
- // Get current root
1055
- const root = tree.root();
1056
-
1057
- // Get Merkle path for proof generation
1058
- const path = tree.path(index1);
1059
- // path = { pathElements: Uint8Array[], pathIndices: number[] }
1060
-
1061
- // Get number of leaves
1062
- const numLeaves = tree.totalLeaves;
1063
-
1064
- // Custom tree depth
1065
- const deepTree = new MerkleTree(25); // 25 levels
1066
- ```
472
+ Private swaps normally use Jupiter versioned transactions and address lookup
473
+ tables. Use `buildPrivateSwapInstructions()` to add Veilo's atomic instructions
474
+ to the exact Jupiter route. Preserve Jupiter's account order and duplicate
475
+ accounts. `transactSwap()` is available when a legacy transaction is sufficient.
1067
476
 
1068
- The Merkle tree uses Poseidon hash for all internal nodes.
477
+ The low-level `transact()` and `buildRawTransactInstruction()` exports are for
478
+ custom transaction composition. Most applications should use the helpers above.
1069
479
 
1070
- ---
480
+ ## Important concepts
1071
481
 
1072
- ### 4.5 Transaction Operations
482
+ ### Amounts use base units
1073
483
 
1074
- The SDK supports three types of transactions:
1075
-
1076
- #### Deposits (publicAmount > 0)
484
+ Amounts are `bigint` values or decimal strings in the token's smallest unit:
1077
485
 
1078
486
  ```ts
1079
- import { deposit } from "@veilo/sdk-core";
1080
-
1081
- // Create output UTXO
1082
- const outputUtxo = createOwnedUTXO({
1083
- amount: 1_000_000_000n, // 1 SOL
1084
- mintAddress: pubkeyToField(NATIVE_SOL_MINT),
1085
- keypair: utxoKeypair,
1086
- });
1087
-
1088
- // Zero inputs for deposit
1089
- const input1 = createOwnedZeroUTXO(pubkeyToField(NATIVE_SOL_MINT), utxoKeypair);
1090
- const input2 = createOwnedZeroUTXO(pubkeyToField(NATIVE_SOL_MINT), utxoKeypair);
1091
- const output2 = createOwnedZeroUTXO(
1092
- pubkeyToField(NATIVE_SOL_MINT),
1093
- utxoKeypair,
1094
- );
1095
-
1096
- await deposit({
1097
- program,
1098
- depositor: depositorKeypair,
1099
- mintAddress: NATIVE_SOL_MINT,
1100
- inputTreeId: 0,
1101
- outputTreeId: 0,
1102
- root: tree.root(),
1103
- publicAmount: 1_000_000_000n, // Positive = deposit
1104
- inputs: [input1, input2],
1105
- outputs: [outputUtxo, output2],
1106
- recipient: depositorKeypair.publicKey,
1107
- fee: 0n,
1108
- refund: 0n,
1109
- proof: mockProof,
1110
- });
487
+ import { sol } from "@veilo/sdk-core/config";
1111
488
 
1112
- // Insert outputs into tree
1113
- tree.insert(outputUtxo.commitment);
1114
- tree.insert(output2.commitment);
489
+ const oneSol = sol(1); // 1_000_000_000n lamports
490
+ const fiveUsdc = 5_000_000n; // 5 USDC for a 6-decimal mint
1115
491
  ```
1116
492
 
1117
- #### Withdrawals (publicAmount < 0)
493
+ Avoid JavaScript floating-point values for token arithmetic.
1118
494
 
1119
- ```ts
1120
- import { withdraw } from "@veilo/sdk-core";
1121
-
1122
- // Prepare input with Merkle path
1123
- const input1: InputUTXO = {
1124
- ...ownedUtxo1,
1125
- pathIndex: 0,
1126
- pathElements: tree.path(0).pathElements,
1127
- };
1128
-
1129
- const zeroInput2: InputUTXO = {
1130
- ...createOwnedZeroUTXO(pubkeyToField(NATIVE_SOL_MINT), utxoKeypair),
1131
- pathIndex: 0,
1132
- pathElements: tree.path(0).pathElements,
1133
- };
1134
-
1135
- // Zero outputs
1136
- const output1 = createOwnedZeroUTXO(
1137
- pubkeyToField(NATIVE_SOL_MINT),
1138
- utxoKeypair,
1139
- );
1140
- const output2 = createOwnedZeroUTXO(
1141
- pubkeyToField(NATIVE_SOL_MINT),
1142
- utxoKeypair,
1143
- );
495
+ ### A private note is valuable secret data
1144
496
 
1145
- await withdraw({
1146
- program,
1147
- relayer: relayerKeypair,
1148
- mintAddress: NATIVE_SOL_MINT,
1149
- inputTreeId: 0,
1150
- outputTreeId: 0,
1151
- root: tree.root(),
1152
- publicAmount: -900_000_000n, // Negative = withdrawal (0.9 SOL)
1153
- inputs: [input1, zeroInput2],
1154
- outputs: [output1, output2],
1155
- recipient: recipientKeypair.publicKey,
1156
- fee: 100_000_000n, // 0.1 SOL to relayer
1157
- refund: 0n,
1158
- proof,
1159
- });
1160
- ```
497
+ A note contains the information needed to locate and spend private funds. Store
498
+ it encrypted, never log it, and never send its unencrypted contents to an
499
+ analytics or application server.
1161
500
 
1162
- #### Private Transfers (publicAmount = 0)
501
+ For shielding, prefer `resolveShieldOwner()`. It obtains the spending and note
502
+ viewing keys as a matched pair. Supplying unrelated keys can create a note that
503
+ the recipient cannot discover.
1163
504
 
1164
- ```ts
1165
- import {
1166
- privateTransfer,
1167
- generateKeypair,
1168
- createOwnedUTXO,
1169
- } from "@veilo/sdk-core";
505
+ ### Confirmation comes before local state updates
1170
506
 
1171
- // Create new outputs for recipient
1172
- const recipientKeypair = generateKeypair();
1173
- const output1 = createOwnedUTXO({
1174
- amount: 1_000_000_000n,
1175
- privateKey: recipientKeypair.privateKey,
1176
- mintAddress: NATIVE_SOL_MINT,
1177
- });
507
+ Do not mark notes as spent, insert commitments into a local tree, or persist a
508
+ predicted leaf index until the transaction is confirmed. Use `finalizeShield()`
509
+ for shields and call a deposit's `commit()` callback only after confirmation.
1178
510
 
1179
- await privateTransfer({
1180
- program,
1181
- relayer: relayerKeypair,
1182
- mintAddress: NATIVE_SOL_MINT,
1183
- inputTreeId: 0,
1184
- outputTreeId: 0,
1185
- root: tree.root(),
1186
- publicAmount: 0n, // Zero = private transfer
1187
- inputs: [input1, zeroInput2],
1188
- outputs: [output1, output2],
1189
- recipient: relayerKeypair.publicKey,
1190
- fee: 0n,
1191
- refund: 0n,
1192
- proof,
1193
- });
511
+ ### Proof files are separate
1194
512
 
1195
- // Insert new outputs
1196
- tree.insert(output1.commitment);
1197
- tree.insert(output2.commitment);
1198
- ```
513
+ Circuit `.wasm` and `.zkey` files are intentionally not bundled with the npm
514
+ package because they are large — `files` ships `dist/` only. Provide local
515
+ paths, byte arrays, or hosted URLs to `createTransactionProver()` and
516
+ `createSwapProver()`.
1199
517
 
1200
- #### Low-Level Transaction Function
518
+ Both arguments are optional. Omit them and the prover resolves artifacts from
519
+ disk on first use, first hit wins:
1201
520
 
1202
- For advanced use cases, use the unified `transact` function directly:
521
+ 1. `$VEILO_CIRCUITS_DIR`
522
+ 2. `<package>/circuits` — populated by `npm run copy:circuits`
523
+ 3. `<cwd>/circuits`
524
+ 4. `<cwd>/node_modules/@veilo/sdk-core/circuits`
1203
525
 
1204
526
  ```ts
1205
- import { transact } from "@veilo/sdk-core";
1206
-
1207
- await transact({
1208
- program,
1209
- relayer: relayerKeypair,
1210
- mintAddress: NATIVE_SOL_MINT,
1211
- inputTreeId: 0,
1212
- outputTreeId: 0,
1213
- root: tree.root(),
1214
- publicAmount: 0n,
1215
- inputNullifiers: [nullifier1, nullifier2],
1216
- outputCommitments: [output1.commitment, output2.commitment],
1217
- extData: {
1218
- recipient: recipientPubkey,
1219
- relayer: relayerPubkey,
1220
- fee: 0n,
1221
- refund: 0n,
1222
- claimant: claimantPubkey,
1223
- },
1224
- proof,
1225
- });
527
+ const prover = createTransactionProver(); // resolved from disk
528
+ const prover = createTransactionProver({ wasmPath, zkeyPath }); // explicit
1226
529
  ```
1227
530
 
1228
- ---
531
+ `resolveCircuitArtifacts("transaction" | "swap")` performs that lookup on its
532
+ own if you want the paths. Resolution is **Node-only and lazy** — it imports
533
+ `node:fs` inside the call so browser bundles can still import this module, and
534
+ there is nothing to resolve in a browser anyway. Browser builds must pass
535
+ `CircuitArtifacts` explicitly. A miss throws with every path it tried.
1229
536
 
1230
- ### 4.6 Proof Generation
537
+ ## Error handling
1231
538
 
1232
- The SDK provides utilities for preparing circuit inputs:
539
+ Shield and Cloak errors include stable fields that applications can use to show
540
+ useful recovery actions.
1233
541
 
1234
542
  ```ts
1235
543
  import {
1236
- prepareTransactionInputs,
1237
- formatInputsForSnarkjs,
1238
- computeExtDataHash,
1239
- encodeSnarkjsProofToTransactionProof,
1240
- packProofToBytes,
1241
- type ExtData,
1242
- type TransactionCircuitInputs,
544
+ CloakApiError,
545
+ mapShieldError,
1243
546
  } from "@veilo/sdk-core";
1244
547
 
1245
- // Prepare inputs for the circuit
1246
- const circuitInputs: TransactionCircuitInputs = prepareTransactionInputs({
1247
- root: tree.root(),
1248
- publicAmount: 1_000_000_000n,
1249
- extData: {
1250
- recipient: recipientPubkey,
1251
- relayer: relayerPubkey,
1252
- fee: 0n,
1253
- refund: 0n,
1254
- claimant: claimantPubkey,
1255
- },
1256
- mintAddress: NATIVE_SOL_MINT,
1257
- inputs: [input1, input2],
1258
- outputs: [output1, output2],
1259
- inputTreeId: 0,
1260
- outputTreeId: 0,
1261
- });
1262
-
1263
- // Format for snarkjs (converts Uint8Array to string representations)
1264
- const snarkjsInputs = formatInputsForSnarkjs(circuitInputs);
1265
-
1266
- // Use with snarkjs to generate proof
1267
- // const { proof, publicSignals } = await snarkjs.groth16.fullProve(
1268
- // snarkjsInputs,
1269
- // wasmPath,
1270
- // zkeyPath
1271
- // );
1272
-
1273
- // Convert snarkjs proof to on-chain format
1274
- // const transactionProof = encodeSnarkjsProofToTransactionProof(proof);
548
+ try {
549
+ // Build or submit a Veilo operation.
550
+ } catch (error) {
551
+ if (error instanceof CloakApiError) {
552
+ console.error(error.code, error.status, error.message);
553
+ } else {
554
+ const shieldError = mapShieldError(error);
555
+ console.error(shieldError.code, shieldError.message);
556
+ // retryable is `rebuild`, `reshield`, or `none`.
557
+ console.log(shieldError.retryable);
558
+ }
559
+ }
1275
560
  ```
1276
561
 
1277
- ---
562
+ When handling Cloak separately, `CloakApiError` also exposes actionable values
563
+ such as `min`, `max`, `field`, `maxBps`, and `retryAfter` when the API returns
564
+ them.
1278
565
 
1279
- ### 4.7 Relayer Management
566
+ ## Package entry points
1280
567
 
1281
- ```ts
1282
- import { addRelayer, setPaused } from "@veilo/sdk-core";
1283
-
1284
- // Add a relayer
1285
- await addRelayer({
1286
- program,
1287
- admin: adminKeypair,
1288
- mintAddress: NATIVE_SOL_MINT,
1289
- newRelayer: relayerPubkey,
1290
- });
1291
-
1292
- // Pause/unpause the pool
1293
- await setPaused({
1294
- program,
1295
- admin: adminKeypair,
1296
- mintAddress: NATIVE_SOL_MINT,
1297
- paused: true,
1298
- });
1299
- ```
1300
-
1301
- ---
1302
-
1303
- ### 4.8 Poseidon Utilities
568
+ Import from the package root for convenience or use a focused entry point:
1304
569
 
1305
570
  ```ts
1306
- import {
1307
- initPoseidon,
1308
- poseidon1,
1309
- poseidon2,
1310
- poseidon3,
1311
- poseidon4,
1312
- pubkeyToField,
1313
- } from "@veilo/sdk-core";
1314
-
1315
- // Initialize Poseidon (required once before using hash functions)
1316
- await initPoseidon();
1317
-
1318
- // Hash functions
1319
- const hash1 = poseidon1(12345n);
1320
- const hash2 = poseidon2(12345n, 67890n);
1321
- const hash3 = poseidon3(12345n, 67890n, 11111n);
1322
- const hash4 = poseidon4(12345n, 67890n, 11111n, 22222n);
1323
-
1324
- // Convert Solana PublicKey to field element
1325
- const fieldElement = pubkeyToField(NATIVE_SOL_MINT);
571
+ import { shield } from "@veilo/sdk-core";
572
+ import { getPoolPdas } from "@veilo/sdk-core/accounts";
573
+ import { createUTXO } from "@veilo/sdk-core/notes";
574
+ import { deposit, withdraw } from "@veilo/sdk-core/transactions";
575
+ import { submitWithdraw } from "@veilo/sdk-core/relayer";
576
+ import { VeiloCloakClient } from "@veilo/sdk-core/cloak";
577
+ import { derivePositionKeyBundle } from "@veilo/sdk-core/positions";
578
+ import { getJperpMarketPayload } from "@veilo/sdk-core/perps";
579
+ import { JupiterPredictionClient } from "@veilo/sdk-core/predictions";
1326
580
  ```
1327
581
 
1328
- ---
1329
-
1330
- ## 5. Architecture
1331
-
1332
- ### Transaction Model
1333
-
1334
- Veilo uses a UTXO-based privacy model inspired by Zcash and Tornado Cash Nova:
582
+ Available focused entry points:
1335
583
 
1336
- 1. **Inputs**: 2 UTXOs (can be zero for deposits)
1337
- 2. **Outputs**: 2 UTXOs (can be zero for withdrawals)
1338
- 3. **Public Amount**: Net change (positive = deposit, negative = withdrawal, zero = private transfer)
584
+ - `@veilo/sdk-core/accounts`
585
+ - `@veilo/sdk-core/cloak`
586
+ - `@veilo/sdk-core/config`
587
+ - `@veilo/sdk-core/idl`
588
+ - `@veilo/sdk-core/identity`
589
+ - `@veilo/sdk-core/notes`
590
+ - `@veilo/sdk-core/perps`
591
+ - `@veilo/sdk-core/positions`
592
+ - `@veilo/sdk-core/predictions`
593
+ - `@veilo/sdk-core/poseidon`
594
+ - `@veilo/sdk-core/proof`
595
+ - `@veilo/sdk-core/prover`
596
+ - `@veilo/sdk-core/relayer`
597
+ - `@veilo/sdk-core/shield`
598
+ - `@veilo/sdk-core/transactions`
1339
599
 
1340
- Each transaction:
600
+ ## Advanced building blocks
1341
601
 
1342
- - Consumes 2 input UTXOs (proven via Merkle paths)
1343
- - Creates 2 output UTXOs (commitments added to tree)
1344
- - Generates 2 nullifiers (prevents double-spending)
1345
- - Optionally transfers funds in/out of the pool
602
+ The root package also exports tools for teams building their own Veilo wallet
603
+ or relayer:
1346
604
 
1347
- ### Privacy Guarantees
605
+ - account and PDA queries;
606
+ - UTXO creation, ownership, encryption, and recovery;
607
+ - Merkle tree reconstruction from on-chain events;
608
+ - transaction and swap witness preparation;
609
+ - Poseidon hashing helpers;
610
+ - pool initialization and administration;
611
+ - raw IDL-correct transaction instruction builders.
1348
612
 
1349
- - **Commitment hiding**: Amount, owner, and blinding factor are hidden via Poseidon hash
1350
- - **Nullifier uniqueness**: Each UTXO can only be spent once
1351
- - **Unlinkability**: No public link between inputs and outputs
1352
- - **Zero-knowledge proofs**: Transactions proven valid without revealing private data
613
+ These APIs are fully typed. Use their TypeScript definitions as the source of
614
+ truth for required inputs.
1353
615
 
1354
- ### Multi-Tree Support
616
+ ### Historical IDLs and commitment recovery
1355
617
 
1356
- The protocol supports multiple concurrent Merkle trees per pool:
1357
-
1358
- - Improves scalability by reducing tree depth
1359
- - Allows parallel insertions
1360
- - Each tree has independent state
1361
-
1362
- ### Constants
618
+ The SDK includes the current, legacy, and legacy-2 privacy-pool IDLs used by the
619
+ relayer. Event scans automatically try the historical layouts, so applications
620
+ can rebuild trees across program upgrades.
1363
621
 
1364
622
  ```ts
1365
623
  import {
1366
- NATIVE_SOL_MINT, // PublicKey.default (all zeros) for native SOL
1367
- MERKLE_TREE_DEPTH, // 22 levels
1368
- ROOT_HISTORY_SIZE, // 256 historical roots
1369
- DEFAULT_FEE_BPS, // 50 (0.5%)
1370
- sol, // Helper: sol(1) = 1_000_000_000n lamports
1371
- } from "@veilo/sdk-core/config";
1372
-
1373
- import { BN254_FR_MODULUS } from "@veilo/sdk-core";
1374
- ```
1375
-
1376
- ### Type Exports
1377
-
1378
- The SDK exports the following types for TypeScript users:
1379
-
1380
- ```ts
1381
- import type {
1382
- // UTXO types
1383
- Keypair,
1384
- UTXO,
1385
- SerializedUTXO,
1386
- InputUTXO,
1387
-
1388
- // Proof types
1389
- ExtData,
1390
- TransactionCircuitInputs,
1391
- TransactionProofStruct,
1392
- RawProof,
1393
- TransactionProofBuilder,
1394
-
1395
- // Merkle types
1396
- MerklePath,
1397
- CircuitMerklePath,
1398
-
1399
- // Config types
1400
- PoolInitConfig,
1401
- PrivacyConfigAccount,
1402
- GlobalConfigAccount,
624
+ PRIVACY_POOL_IDLS,
625
+ buildTreeFromEvents,
626
+ resolveCommitmentEvents,
1403
627
  } from "@veilo/sdk-core";
1404
628
  ```
1405
629
 
1406
- ### SPL Token Support
1407
-
1408
- The SDK supports both native SOL and SPL tokens:
1409
-
1410
- ```ts
1411
- import { PublicKey } from "@solana/web3.js";
1412
-
1413
- // For native SOL
1414
- const solMint = NATIVE_SOL_MINT; // PublicKey.default
1415
-
1416
- // For SPL tokens
1417
- const usdcMint = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
1418
-
1419
- // Initialize pool for SPL token
1420
- await initializePool({
1421
- program,
1422
- payer: adminKeypair,
1423
- admin: adminKeypair,
1424
- mintAddress: usdcMint, // Use SPL token mint
1425
- minDepositAmount: 1_000_000n, // 1 USDC (6 decimals)
1426
- // ... other params
1427
- });
1428
- ```
1429
-
1430
- When using SPL tokens, the SDK automatically handles associated token accounts.
630
+ `buildTreeFromEvents()` includes Veilo's protected historical repairs by
631
+ default and rejects gaps that would produce an incorrect root. When a confirmed
632
+ instruction appended commitments without emitting `CommitmentEvent`, use
633
+ `resolveCommitmentEvents()` with the expected commitments and current local
634
+ tree. It prefers emitted metadata and computes only the missing entries.
1431
635
 
1432
- ---
636
+ For the deployed eventless `open_position` path, use
637
+ `recoverEventlessOpenPositionEvents()`. It decodes both commitments from the
638
+ instruction and reads the authoritative global position-tree leaf index from
639
+ the program-owned PositionPDA. `buildGlobalPositionTreeFromEvents()` mirrors
640
+ the relayer's all-mint position-tree reconstruction.
1433
641
 
1434
- ## 6. Development
1435
-
1436
- ### Environment Variables
642
+ ## Development
1437
643
 
1438
644
  ```bash
1439
- export ANCHOR_PROVIDER_URL=http://127.0.0.1:8899
1440
- export ANCHOR_WALLET=$HOME/.config/solana/id.json
1441
- ```
1442
-
1443
- ---
645
+ # Build CommonJS, ESM, and declaration outputs
646
+ npm run build
1444
647
 
1445
- ## 7. Limitations
648
+ # Run deterministic unit and proof tests
649
+ npm test
1446
650
 
1447
- - **Off-chain tree management**: Merkle trees must be maintained by relayers/clients
1448
- - **Proof generation not included**: You must integrate your own circuit/prover
1449
- - **Development status**: Active development, APIs may change
651
+ # Run opt-in live Devnet integration tests
652
+ npm run test:integration
1450
653
 
1451
- ---
654
+ # Check module boundaries for dependency cycles
655
+ npm run check:cycles
656
+ ```
1452
657
 
1453
- ## 8. Resources
658
+ ## Support
1454
659
 
1455
- - **Repository**: https://github.com/VeiloSolana/veilo-sdk
1456
- - **Circomlibjs**: https://github.com/iden3/circomlibjs
1457
- - **Poseidon Hash**: https://www.poseidon-hash.info/
660
+ - [Repository](https://github.com/VeiloSolana/veilo-sdk)
661
+ - [Issue tracker](https://github.com/VeiloSolana/veilo-sdk/issues)
1458
662
 
1459
- ---
663
+ When reporting a problem, include the SDK version, runtime, Solana cluster, and
664
+ the error's `code` and `status` or `programCode` where available. Never include
665
+ private notes, wallet secret keys, API keys, or authentication tokens.
1460
666
 
1461
667
  ## License
1462
668
 
1463
- ISC
669
+ [ISC](./LICENSE)