@veilo/sdk-core 0.4.0 → 0.5.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 (296) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +286 -1298
  3. package/dist/cjs/accounts/admin.d.ts +84 -0
  4. package/dist/cjs/accounts/admin.js +208 -0
  5. package/dist/cjs/accounts/errors.d.ts +6 -0
  6. package/dist/cjs/accounts/errors.js +98 -0
  7. package/dist/cjs/accounts/index.d.ts +4 -0
  8. package/dist/cjs/accounts/index.js +20 -0
  9. package/dist/cjs/accounts/pdas.d.ts +23 -0
  10. package/dist/cjs/accounts/pdas.js +44 -0
  11. package/dist/cjs/accounts/queries.d.ts +41 -0
  12. package/dist/cjs/accounts/queries.js +95 -0
  13. package/dist/cjs/client.d.ts +2 -407
  14. package/dist/cjs/client.js +6 -938
  15. package/dist/cjs/cloak/client.d.ts +28 -0
  16. package/dist/cjs/cloak/client.js +68 -0
  17. package/dist/cjs/cloak/errors.d.ts +13 -0
  18. package/dist/cjs/cloak/errors.js +25 -0
  19. package/dist/cjs/cloak/helpers.d.ts +6 -0
  20. package/dist/cjs/cloak/helpers.js +35 -0
  21. package/dist/cjs/cloak/index.d.ts +6 -0
  22. package/dist/cjs/cloak/index.js +24 -0
  23. package/dist/cjs/cloak/polling.d.ts +7 -0
  24. package/dist/cjs/cloak/polling.js +66 -0
  25. package/dist/cjs/cloak/transport.d.ts +15 -0
  26. package/dist/cjs/cloak/transport.js +119 -0
  27. package/dist/cjs/cloak/types.d.ts +188 -0
  28. package/dist/cjs/cloak/types.js +5 -0
  29. package/dist/cjs/cloak.d.ts +1 -0
  30. package/dist/cjs/cloak.js +18 -0
  31. package/dist/cjs/compactNote.d.ts +21 -0
  32. package/dist/cjs/compactNote.js +31 -7
  33. package/dist/cjs/index.d.ts +2 -1
  34. package/dist/cjs/index.js +4 -1
  35. package/dist/cjs/notes/encryption.d.ts +41 -0
  36. package/dist/cjs/notes/encryption.js +75 -0
  37. package/dist/cjs/notes/index.d.ts +5 -0
  38. package/dist/cjs/notes/index.js +21 -0
  39. package/dist/cjs/notes/mailbox.d.ts +70 -0
  40. package/dist/cjs/notes/mailbox.js +164 -0
  41. package/dist/cjs/notes/model.d.ts +91 -0
  42. package/dist/cjs/notes/model.js +109 -0
  43. package/dist/cjs/notes/nullifier.d.ts +27 -0
  44. package/dist/cjs/notes/nullifier.js +45 -0
  45. package/dist/cjs/notes/recovery.d.ts +10 -0
  46. package/dist/cjs/notes/recovery.js +31 -0
  47. package/dist/cjs/proof.d.ts +1 -183
  48. package/dist/cjs/proof.js +16 -290
  49. package/dist/cjs/proofs/encoding.d.ts +17 -0
  50. package/dist/cjs/proofs/encoding.js +72 -0
  51. package/dist/cjs/proofs/formatting.d.ts +6 -0
  52. package/dist/cjs/proofs/formatting.js +34 -0
  53. package/dist/cjs/proofs/index.d.ts +5 -0
  54. package/dist/cjs/proofs/index.js +21 -0
  55. package/dist/cjs/proofs/swap.d.ts +87 -0
  56. package/dist/cjs/proofs/swap.js +144 -0
  57. package/dist/cjs/proofs/transaction.d.ts +28 -0
  58. package/dist/cjs/proofs/transaction.js +110 -0
  59. package/dist/cjs/proofs/types.d.ts +70 -0
  60. package/dist/cjs/prover.d.ts +4 -1
  61. package/dist/cjs/prover.js +12 -2
  62. package/dist/cjs/relayer/client.d.ts +61 -0
  63. package/dist/cjs/relayer/client.js +151 -0
  64. package/dist/cjs/relayer/crypto.d.ts +5 -0
  65. package/dist/cjs/relayer/crypto.js +26 -0
  66. package/dist/cjs/relayer/encoding.d.ts +2 -0
  67. package/dist/cjs/relayer/encoding.js +23 -0
  68. package/dist/cjs/relayer/errors.d.ts +7 -0
  69. package/dist/cjs/relayer/errors.js +17 -0
  70. package/dist/cjs/relayer/index.d.ts +3 -0
  71. package/dist/cjs/relayer/index.js +19 -0
  72. package/dist/cjs/relayer/transport.d.ts +17 -0
  73. package/dist/cjs/relayer/transport.js +63 -0
  74. package/dist/{src/relayer.d.ts → cjs/relayer/types.d.ts} +44 -86
  75. package/dist/cjs/relayer/types.js +5 -0
  76. package/dist/cjs/relayer.d.ts +1 -318
  77. package/dist/cjs/relayer.js +15 -254
  78. package/dist/cjs/shield/alt.js +8 -8
  79. package/dist/cjs/shield/errors.js +2 -2
  80. package/dist/cjs/shield/finalize.js +2 -2
  81. package/dist/cjs/shield/ix.d.ts +1 -1
  82. package/dist/cjs/shield/owner.js +9 -8
  83. package/dist/cjs/shield/ports.js +3 -3
  84. package/dist/cjs/shield/preflight.js +3 -3
  85. package/dist/cjs/shield/shield.js +20 -19
  86. package/dist/cjs/shield/types.d.ts +1 -1
  87. package/dist/cjs/transactions/deposit.d.ts +94 -0
  88. package/dist/cjs/transactions/deposit.js +234 -0
  89. package/dist/cjs/transactions/index.d.ts +7 -0
  90. package/dist/cjs/transactions/index.js +26 -0
  91. package/dist/cjs/transactions/swap.d.ts +71 -0
  92. package/dist/cjs/transactions/swap.js +184 -0
  93. package/dist/cjs/transactions/transact.d.ts +34 -0
  94. package/dist/cjs/transactions/transact.js +146 -0
  95. package/dist/cjs/transactions/transfer.d.ts +51 -0
  96. package/dist/cjs/transactions/transfer.js +106 -0
  97. package/dist/cjs/transactions/withdraw.d.ts +52 -0
  98. package/dist/cjs/transactions/withdraw.js +104 -0
  99. package/dist/cjs/utxo.d.ts +1 -235
  100. package/dist/cjs/utxo.js +15 -404
  101. package/dist/esm/accounts/admin.d.ts +84 -0
  102. package/dist/esm/accounts/admin.js +165 -0
  103. package/dist/esm/accounts/errors.d.ts +6 -0
  104. package/dist/esm/accounts/errors.js +95 -0
  105. package/dist/esm/accounts/index.d.ts +4 -0
  106. package/dist/esm/accounts/index.js +4 -0
  107. package/dist/esm/accounts/pdas.d.ts +23 -0
  108. package/dist/esm/accounts/pdas.js +38 -0
  109. package/dist/esm/accounts/queries.d.ts +41 -0
  110. package/dist/esm/accounts/queries.js +88 -0
  111. package/dist/esm/client.d.ts +2 -407
  112. package/dist/esm/client.js +3 -891
  113. package/dist/esm/cloak/client.d.ts +28 -0
  114. package/dist/esm/cloak/client.js +64 -0
  115. package/dist/esm/cloak/errors.d.ts +13 -0
  116. package/dist/esm/cloak/errors.js +21 -0
  117. package/dist/esm/cloak/helpers.d.ts +6 -0
  118. package/dist/esm/cloak/helpers.js +31 -0
  119. package/dist/esm/cloak/index.d.ts +6 -0
  120. package/dist/esm/cloak/index.js +6 -0
  121. package/dist/esm/cloak/polling.d.ts +7 -0
  122. package/dist/esm/cloak/polling.js +63 -0
  123. package/dist/esm/cloak/transport.d.ts +15 -0
  124. package/dist/esm/cloak/transport.js +115 -0
  125. package/dist/esm/cloak/types.d.ts +188 -0
  126. package/dist/esm/cloak/types.js +4 -0
  127. package/dist/esm/cloak.d.ts +1 -0
  128. package/dist/esm/cloak.js +2 -0
  129. package/dist/esm/compactNote.d.ts +21 -0
  130. package/dist/esm/compactNote.js +24 -1
  131. package/dist/esm/index.d.ts +2 -1
  132. package/dist/esm/index.js +3 -1
  133. package/dist/esm/notes/encryption.d.ts +41 -0
  134. package/dist/esm/notes/encryption.js +67 -0
  135. package/dist/esm/notes/index.d.ts +5 -0
  136. package/dist/esm/notes/index.js +5 -0
  137. package/dist/esm/notes/mailbox.d.ts +70 -0
  138. package/dist/esm/notes/mailbox.js +154 -0
  139. package/dist/esm/notes/model.d.ts +91 -0
  140. package/dist/esm/notes/model.js +99 -0
  141. package/dist/esm/notes/nullifier.d.ts +27 -0
  142. package/dist/esm/notes/nullifier.js +40 -0
  143. package/dist/esm/notes/recovery.d.ts +10 -0
  144. package/dist/esm/notes/recovery.js +28 -0
  145. package/dist/esm/proof.d.ts +1 -183
  146. package/dist/esm/proof.js +2 -281
  147. package/dist/esm/proofs/encoding.d.ts +17 -0
  148. package/dist/esm/proofs/encoding.js +68 -0
  149. package/dist/esm/proofs/formatting.d.ts +6 -0
  150. package/dist/esm/proofs/formatting.js +31 -0
  151. package/dist/esm/proofs/index.d.ts +5 -0
  152. package/dist/esm/proofs/index.js +5 -0
  153. package/dist/esm/proofs/swap.d.ts +87 -0
  154. package/dist/esm/proofs/swap.js +138 -0
  155. package/dist/esm/proofs/transaction.d.ts +28 -0
  156. package/dist/esm/proofs/transaction.js +105 -0
  157. package/dist/esm/proofs/types.d.ts +70 -0
  158. package/dist/esm/proofs/types.js +1 -0
  159. package/dist/esm/prover.d.ts +4 -1
  160. package/dist/esm/prover.js +10 -1
  161. package/dist/esm/relayer/client.d.ts +61 -0
  162. package/dist/esm/relayer/client.js +144 -0
  163. package/dist/esm/relayer/crypto.d.ts +5 -0
  164. package/dist/esm/relayer/crypto.js +20 -0
  165. package/dist/esm/relayer/encoding.d.ts +2 -0
  166. package/dist/esm/relayer/encoding.js +19 -0
  167. package/dist/esm/relayer/errors.d.ts +7 -0
  168. package/dist/esm/relayer/errors.js +13 -0
  169. package/dist/esm/relayer/index.d.ts +3 -0
  170. package/dist/esm/relayer/index.js +3 -0
  171. package/dist/esm/relayer/transport.d.ts +17 -0
  172. package/dist/esm/relayer/transport.js +59 -0
  173. package/dist/esm/relayer/types.d.ts +276 -0
  174. package/dist/esm/relayer/types.js +4 -0
  175. package/dist/esm/relayer.d.ts +1 -318
  176. package/dist/esm/relayer.js +2 -249
  177. package/dist/esm/shield/alt.js +1 -1
  178. package/dist/esm/shield/errors.js +1 -1
  179. package/dist/esm/shield/finalize.js +1 -1
  180. package/dist/esm/shield/ix.d.ts +1 -1
  181. package/dist/esm/shield/owner.js +2 -1
  182. package/dist/esm/shield/ports.js +1 -1
  183. package/dist/esm/shield/preflight.js +1 -1
  184. package/dist/esm/shield/shield.js +4 -3
  185. package/dist/esm/shield/types.d.ts +1 -1
  186. package/dist/esm/transactions/deposit.d.ts +94 -0
  187. package/dist/esm/transactions/deposit.js +198 -0
  188. package/dist/esm/transactions/index.d.ts +7 -0
  189. package/dist/esm/transactions/index.js +7 -0
  190. package/dist/esm/transactions/swap.d.ts +71 -0
  191. package/dist/esm/transactions/swap.js +144 -0
  192. package/dist/esm/transactions/transact.d.ts +34 -0
  193. package/dist/esm/transactions/transact.js +110 -0
  194. package/dist/esm/transactions/transfer.d.ts +51 -0
  195. package/dist/esm/transactions/transfer.js +103 -0
  196. package/dist/esm/transactions/withdraw.d.ts +52 -0
  197. package/dist/esm/transactions/withdraw.js +101 -0
  198. package/dist/esm/utxo.d.ts +1 -235
  199. package/dist/esm/utxo.js +2 -382
  200. package/package.json +54 -16
  201. package/SHIELD_INTEGRATION.md +0 -143
  202. package/config.d.ts +0 -2
  203. package/config.js +0 -4
  204. package/dist/src/client.d.ts +0 -407
  205. package/dist/src/client.js +0 -951
  206. package/dist/src/compactNote.d.ts +0 -107
  207. package/dist/src/compactNote.js +0 -167
  208. package/dist/src/config.d.ts +0 -82
  209. package/dist/src/config.js +0 -57
  210. package/dist/src/events.d.ts +0 -77
  211. package/dist/src/events.js +0 -167
  212. package/dist/src/idl/privacy_pool.d.ts +0 -5
  213. package/dist/src/idl/privacy_pool.js +0 -15218
  214. package/dist/src/index.d.ts +0 -16
  215. package/dist/src/index.js +0 -67
  216. package/dist/src/merkle.d.ts +0 -77
  217. package/dist/src/merkle.js +0 -156
  218. package/dist/src/poseidon.d.ts +0 -29
  219. package/dist/src/poseidon.js +0 -100
  220. package/dist/src/program.d.ts +0 -37
  221. package/dist/src/program.js +0 -61
  222. package/dist/src/proof.d.ts +0 -183
  223. package/dist/src/proof.js +0 -292
  224. package/dist/src/prover.d.ts +0 -54
  225. package/dist/src/prover.js +0 -112
  226. package/dist/src/random.d.ts +0 -16
  227. package/dist/src/random.js +0 -28
  228. package/dist/src/relayer.js +0 -257
  229. package/dist/src/retry.d.ts +0 -32
  230. package/dist/src/retry.js +0 -75
  231. package/dist/src/shield/alt.d.ts +0 -87
  232. package/dist/src/shield/alt.js +0 -194
  233. package/dist/src/shield/computeBudget.d.ts +0 -61
  234. package/dist/src/shield/computeBudget.js +0 -64
  235. package/dist/src/shield/errors.d.ts +0 -58
  236. package/dist/src/shield/errors.js +0 -121
  237. package/dist/src/shield/finalize.d.ts +0 -45
  238. package/dist/src/shield/finalize.js +0 -119
  239. package/dist/src/shield/index.d.ts +0 -35
  240. package/dist/src/shield/index.js +0 -68
  241. package/dist/src/shield/ix.d.ts +0 -54
  242. package/dist/src/shield/ix.js +0 -119
  243. package/dist/src/shield/owner.d.ts +0 -36
  244. package/dist/src/shield/owner.js +0 -126
  245. package/dist/src/shield/ports.d.ts +0 -43
  246. package/dist/src/shield/ports.js +0 -153
  247. package/dist/src/shield/preflight.d.ts +0 -30
  248. package/dist/src/shield/preflight.js +0 -154
  249. package/dist/src/shield/shield.d.ts +0 -68
  250. package/dist/src/shield/shield.js +0 -499
  251. package/dist/src/shield/types.d.ts +0 -202
  252. package/dist/src/utxo.d.ts +0 -235
  253. package/dist/src/utxo.js +0 -407
  254. package/dist/tests/compact-note.test.d.ts +0 -1
  255. package/dist/tests/compact-note.test.js +0 -173
  256. package/dist/tests/config.test.d.ts +0 -1
  257. package/dist/tests/config.test.js +0 -102
  258. package/dist/tests/edge-cases.test.d.ts +0 -1
  259. package/dist/tests/edge-cases.test.js +0 -220
  260. package/dist/tests/encryption.test.d.ts +0 -1
  261. package/dist/tests/encryption.test.js +0 -215
  262. package/dist/tests/events.test.d.ts +0 -1
  263. package/dist/tests/events.test.js +0 -78
  264. package/dist/tests/multi-tree.test.d.ts +0 -1
  265. package/dist/tests/multi-tree.test.js +0 -405
  266. package/dist/tests/pda.test.d.ts +0 -1
  267. package/dist/tests/pda.test.js +0 -229
  268. package/dist/tests/poseidon-builder-parity.test.d.ts +0 -1
  269. package/dist/tests/poseidon-builder-parity.test.js +0 -72
  270. package/dist/tests/poseidon.test.d.ts +0 -1
  271. package/dist/tests/poseidon.test.js +0 -142
  272. package/dist/tests/proof.test.d.ts +0 -1
  273. package/dist/tests/proof.test.js +0 -296
  274. package/dist/tests/relayer.test.d.ts +0 -1
  275. package/dist/tests/relayer.test.js +0 -271
  276. package/dist/tests/sdk.integration.test.d.ts +0 -1
  277. package/dist/tests/sdk.integration.test.js +0 -330
  278. package/dist/tests/shield-owner.test.d.ts +0 -1
  279. package/dist/tests/shield-owner.test.js +0 -89
  280. package/dist/tests/shield-preflight.test.d.ts +0 -1
  281. package/dist/tests/shield-preflight.test.js +0 -87
  282. package/dist/tests/shield-realproof.test.d.ts +0 -1
  283. package/dist/tests/shield-realproof.test.js +0 -272
  284. package/dist/tests/shield.test.d.ts +0 -1
  285. package/dist/tests/shield.test.js +0 -403
  286. package/dist/tests/utxo.test.d.ts +0 -1
  287. package/dist/tests/utxo.test.js +0 -140
  288. package/poseidon.d.ts +0 -2
  289. package/poseidon.js +0 -4
  290. package/proof.d.ts +0 -2
  291. package/proof.js +0 -4
  292. package/prover.d.ts +0 -2
  293. package/prover.js +0 -4
  294. package/shield.d.ts +0 -2
  295. package/shield.js +0 -4
  296. /package/dist/{src/shield → cjs/proofs}/types.js +0 -0
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.transact = transact;
37
+ const anchor = __importStar(require("@coral-xyz/anchor"));
38
+ const web3_js_1 = require("@solana/web3.js");
39
+ const spl_token_1 = require("@solana/spl-token");
40
+ const transaction_js_1 = require("../proofs/transaction.js");
41
+ const config_js_1 = require("../config.js");
42
+ const retry_js_1 = require("../retry.js");
43
+ const pdas_js_1 = require("../accounts/pdas.js");
44
+ // Anchor is CJS and does not expose BN as a detectable Node ESM named export.
45
+ const { BN } = anchor;
46
+ // -----------------------------------------------------------------------------
47
+ // Main Transaction Instruction
48
+ // -----------------------------------------------------------------------------
49
+ /**
50
+ * Execute a transaction on the privacy pool.
51
+ * This is the low-level function that calls the on-chain `transact` instruction.
52
+ *
53
+ * @param publicAmount - Positive for deposits, negative for withdrawals, 0 for transfers
54
+ * @param inputTreeId - The tree ID where input UTXOs are located
55
+ * @param outputTreeId - The tree ID where output commitments will be inserted
56
+ */
57
+ async function transact(params) {
58
+ const { program, relayer, recipient, mintAddress, root, inputTreeId, outputTreeId, publicAmount, inputNullifiers, outputCommitments, extData, proof, deadline = BigInt(Math.floor(Date.now() / 1000) + 600), noteCiphers = null, vaultTokenAccount, userTokenAccount, recipientTokenAccount, relayerTokenAccount, } = params;
59
+ if (!recipient.equals(extData.recipient)) {
60
+ throw new Error("recipient account must match extData.recipient");
61
+ }
62
+ if (!relayer.publicKey.equals(extData.relayer)) {
63
+ throw new Error("relayer account must match extData.relayer");
64
+ }
65
+ if (deadline <= 0n) {
66
+ throw new Error("deadline must be a positive Unix timestamp");
67
+ }
68
+ if (publicAmount === 0n && (extData.fee !== 0n || extData.refund !== 0n)) {
69
+ throw new Error("Private transfers require extData fee and refund to be zero");
70
+ }
71
+ const { config, vault, nullifiers } = (0, pdas_js_1.getPoolPdas)(program.programId, mintAddress);
72
+ const globalConfig = (0, pdas_js_1.getGlobalConfigPda)(program.programId);
73
+ const inputTree = (0, pdas_js_1.getNoteTreePda)(program.programId, mintAddress, inputTreeId);
74
+ const outputTree = (0, pdas_js_1.getNoteTreePda)(program.programId, mintAddress, outputTreeId);
75
+ // Nullifier markers are global (no tree_id) to prevent cross-tree double-spend
76
+ const nullifierMarker0 = (0, pdas_js_1.getNullifierMarkerPda)(program.programId, mintAddress, inputNullifiers[0]);
77
+ const nullifierMarker1 = (0, pdas_js_1.getNullifierMarkerPda)(program.programId, mintAddress, inputNullifiers[1]);
78
+ const extDataHash = (0, transaction_js_1.computeExtDataHash)(extData);
79
+ const isNativeSol = mintAddress.equals(config_js_1.NATIVE_SOL_MINT);
80
+ // For SPL tokens, resolve token accounts
81
+ let vaultTA = vaultTokenAccount;
82
+ let userTA = userTokenAccount;
83
+ let recipientTA = recipientTokenAccount;
84
+ let relayerTA = relayerTokenAccount;
85
+ if (!isNativeSol) {
86
+ if (!vaultTA) {
87
+ vaultTA = await (0, spl_token_1.getAssociatedTokenAddress)(mintAddress, vault, true);
88
+ }
89
+ if (!userTA) {
90
+ userTA = await (0, spl_token_1.getAssociatedTokenAddress)(mintAddress, relayer.publicKey);
91
+ }
92
+ if (!recipientTA) {
93
+ recipientTA = await (0, spl_token_1.getAssociatedTokenAddress)(mintAddress, recipient);
94
+ }
95
+ if (!relayerTA) {
96
+ relayerTA = await (0, spl_token_1.getAssociatedTokenAddress)(mintAddress, relayer.publicKey);
97
+ }
98
+ }
99
+ else {
100
+ vaultTA ?? (vaultTA = relayer.publicKey);
101
+ userTA ?? (userTA = relayer.publicKey);
102
+ recipientTA ?? (recipientTA = relayer.publicKey);
103
+ relayerTA ?? (relayerTA = relayer.publicKey);
104
+ }
105
+ const tx = program.methods
106
+ .transact(Array.from(root), inputTreeId, outputTreeId, new BN(publicAmount.toString()), Array.from(extDataHash), mintAddress, Array.from(inputNullifiers[0]), Array.from(inputNullifiers[1]), Array.from(outputCommitments[0]), Array.from(outputCommitments[1]), new BN(deadline.toString()), {
107
+ recipient: extData.recipient,
108
+ relayer: extData.relayer,
109
+ fee: new BN(extData.fee.toString()),
110
+ refund: new BN(extData.refund.toString()),
111
+ claimant: extData.claimant,
112
+ }, {
113
+ proofA: proof.proofA,
114
+ proofB: proof.proofB,
115
+ proofC: proof.proofC,
116
+ }, noteCiphers
117
+ ? {
118
+ note0EphemeralKey: Array.from(noteCiphers.note0EphemeralKey),
119
+ note0Encrypted: Array.from(noteCiphers.note0Encrypted),
120
+ note0ViewTag: noteCiphers.note0ViewTag,
121
+ note1EphemeralKey: Array.from(noteCiphers.note1EphemeralKey),
122
+ note1Encrypted: Array.from(noteCiphers.note1Encrypted),
123
+ note1ViewTag: noteCiphers.note1ViewTag,
124
+ }
125
+ : null)
126
+ .accountsStrict({
127
+ config,
128
+ globalConfig,
129
+ vault,
130
+ inputTree,
131
+ outputTree,
132
+ nullifiers,
133
+ nullifierMarker0,
134
+ nullifierMarker1,
135
+ relayer: relayer.publicKey,
136
+ recipient,
137
+ vaultTokenAccount: vaultTA,
138
+ userTokenAccount: userTA,
139
+ recipientTokenAccount: recipientTA,
140
+ relayerTokenAccount: relayerTA,
141
+ tokenProgram: isNativeSol ? web3_js_1.SystemProgram.programId : spl_token_1.TOKEN_PROGRAM_ID,
142
+ systemProgram: web3_js_1.SystemProgram.programId,
143
+ })
144
+ .signers([relayer]);
145
+ return (0, retry_js_1.withRpcRetry)(() => tx.rpc());
146
+ }
@@ -0,0 +1,51 @@
1
+ import type { Program, Idl } from "@coral-xyz/anchor";
2
+ import { Keypair, PublicKey } from "@solana/web3.js";
3
+ import type { TransactionProofBuilder } from "../proofs/types.js";
4
+ import type { InputUTXO, SerializedUTXO } from "../notes/model.js";
5
+ import { MerkleTree } from "../merkle.js";
6
+ import { type NoteCiphers } from "../compactNote.js";
7
+ export type TransferResult = {
8
+ /** Output UTXOs created by the transfer */
9
+ outputUTXOs: [SerializedUTXO, SerializedUTXO];
10
+ /** Leaf indices where the UTXOs were inserted */
11
+ leafIndices: [number, number];
12
+ /** New Merkle root after insertion */
13
+ root: Uint8Array;
14
+ };
15
+ /**
16
+ * Execute a private transfer within the pool.
17
+ *
18
+ * For transfers, the publicAmount is 0 (no funds enter or leave the pool).
19
+ * Input amounts must equal output amounts.
20
+ *
21
+ * @param inputUTXOs - The UTXOs being spent
22
+ * @param outputPubkeys - UTXO public keys for the recipients
23
+ * @param outputAmounts - Amounts for each output (must sum to input total)
24
+ * @param inputTreeId - The tree ID where input UTXOs are located
25
+ * @param outputTreeId - The tree ID where output commitments will be inserted
26
+ */
27
+ export declare function privateTransfer<T extends Idl>(params: {
28
+ program: Program<T>;
29
+ relayer: Keypair;
30
+ mintAddress: PublicKey;
31
+ inputUTXOs: [InputUTXO, InputUTXO];
32
+ outputPubkeys: [bigint, bigint];
33
+ outputAmounts: [bigint, bigint];
34
+ root: Uint8Array;
35
+ inputTreeId: number;
36
+ outputTreeId: number;
37
+ tree: MerkleTree;
38
+ proofBuilder: TransactionProofBuilder;
39
+ /** Must be zero: the program rejects fees on publicAmount=0 transfers. */
40
+ fee?: bigint;
41
+ deadline?: bigint;
42
+ /** Public recipient account committed in ExtData (no funds are sent to it). */
43
+ externalRecipient?: PublicKey;
44
+ /** Wallet keys used to encrypt output notes for on-chain recovery. */
45
+ noteRecipientWallets?: [
46
+ PublicKey | Uint8Array | null,
47
+ PublicKey | Uint8Array | null
48
+ ];
49
+ /** Prebuilt note ciphers. Takes precedence over noteRecipientWallets. */
50
+ noteCiphers?: NoteCiphers | null;
51
+ }): Promise<TransferResult>;
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.privateTransfer = privateTransfer;
4
+ const web3_js_1 = require("@solana/web3.js");
5
+ const transaction_js_1 = require("../proofs/transaction.js");
6
+ const encoding_js_1 = require("../proofs/encoding.js");
7
+ const model_js_1 = require("../notes/model.js");
8
+ const transact_js_1 = require("./transact.js");
9
+ const poseidon_js_1 = require("../poseidon.js");
10
+ const compactNote_js_1 = require("../compactNote.js");
11
+ /**
12
+ * Execute a private transfer within the pool.
13
+ *
14
+ * For transfers, the publicAmount is 0 (no funds enter or leave the pool).
15
+ * Input amounts must equal output amounts.
16
+ *
17
+ * @param inputUTXOs - The UTXOs being spent
18
+ * @param outputPubkeys - UTXO public keys for the recipients
19
+ * @param outputAmounts - Amounts for each output (must sum to input total)
20
+ * @param inputTreeId - The tree ID where input UTXOs are located
21
+ * @param outputTreeId - The tree ID where output commitments will be inserted
22
+ */
23
+ async function privateTransfer(params) {
24
+ const { program, relayer, mintAddress, inputUTXOs, outputPubkeys, outputAmounts, root, inputTreeId, outputTreeId, tree, proofBuilder, fee = 0n, deadline = BigInt(Math.floor(Date.now() / 1000) + 600), externalRecipient = web3_js_1.Keypair.generate().publicKey, noteRecipientWallets, noteCiphers, } = params;
25
+ if (fee !== 0n) {
26
+ throw new Error("Private transact transfers require fee=0; represent any relayer fee in the output amounts");
27
+ }
28
+ const totalInput = inputUTXOs[0].amount + inputUTXOs[1].amount;
29
+ const totalOutput = outputAmounts[0] + outputAmounts[1];
30
+ if (totalInput !== totalOutput) {
31
+ throw new Error(`Balance mismatch: inputs=${totalInput}, outputs=${totalOutput}`);
32
+ }
33
+ const outputUTXO0 = (0, model_js_1.createUTXO)({
34
+ amount: outputAmounts[0],
35
+ pubkey: outputPubkeys[0],
36
+ mintAddress,
37
+ });
38
+ const outputUTXO1 = (0, model_js_1.createUTXO)({
39
+ amount: outputAmounts[1],
40
+ pubkey: outputPubkeys[1],
41
+ mintAddress,
42
+ });
43
+ const outputUTXOs = [
44
+ outputUTXO0,
45
+ outputUTXO1,
46
+ ];
47
+ const extData = {
48
+ recipient: externalRecipient,
49
+ relayer: relayer.publicKey,
50
+ fee: 0n,
51
+ refund: 0n,
52
+ claimant: web3_js_1.SystemProgram.programId,
53
+ };
54
+ // publicAmount is 0 for transfers
55
+ const publicAmount = 0n;
56
+ const circuitInputs = (0, transaction_js_1.prepareTransactionInputs)({
57
+ inputUTXOs,
58
+ outputUTXOs,
59
+ root,
60
+ publicAmount,
61
+ extData,
62
+ mintAddress,
63
+ });
64
+ const rawProof = await proofBuilder(circuitInputs);
65
+ const proof = (0, encoding_js_1.encodeSnarkjsProofToTransactionProof)(rawProof);
66
+ const walletBytes = (wallet) => wallet instanceof web3_js_1.PublicKey ? wallet.toBytes() : wallet;
67
+ const transferNoteCiphers = noteCiphers ??
68
+ (noteRecipientWallets
69
+ ? (0, compactNote_js_1.createNoteCiphers)(noteRecipientWallets[0]
70
+ ? {
71
+ recipientWalletPubkey: walletBytes(noteRecipientWallets[0]),
72
+ blinding: (0, poseidon_js_1.bigIntToBytesBE)(outputUTXOs[0].blinding),
73
+ amount: outputUTXOs[0].amount,
74
+ }
75
+ : null, noteRecipientWallets[1]
76
+ ? {
77
+ recipientWalletPubkey: walletBytes(noteRecipientWallets[1]),
78
+ blinding: (0, poseidon_js_1.bigIntToBytesBE)(outputUTXOs[1].blinding),
79
+ amount: outputUTXOs[1].amount,
80
+ }
81
+ : null)
82
+ : null);
83
+ await (0, transact_js_1.transact)({
84
+ program,
85
+ relayer,
86
+ recipient: externalRecipient,
87
+ mintAddress,
88
+ root,
89
+ inputTreeId,
90
+ outputTreeId,
91
+ publicAmount,
92
+ inputNullifiers: circuitInputs.inputNullifiers,
93
+ outputCommitments: circuitInputs.outputCommitments,
94
+ extData,
95
+ proof,
96
+ deadline,
97
+ noteCiphers: transferNoteCiphers,
98
+ });
99
+ const { index: outIdx0 } = tree.insert(outputUTXOs[0].commitment);
100
+ const { index: outIdx1, root: newRoot } = tree.insert(outputUTXOs[1].commitment);
101
+ return {
102
+ outputUTXOs,
103
+ leafIndices: [outIdx0, outIdx1],
104
+ root: newRoot,
105
+ };
106
+ }
@@ -0,0 +1,52 @@
1
+ import type { Program, Idl } from "@coral-xyz/anchor";
2
+ import { Keypair, PublicKey } from "@solana/web3.js";
3
+ import type { TransactionProofBuilder } from "../proofs/types.js";
4
+ import type { InputUTXO, SerializedUTXO } from "../notes/model.js";
5
+ import { MerkleTree } from "../merkle.js";
6
+ import { type NoteCiphers } from "../compactNote.js";
7
+ export type WithdrawResult = {
8
+ /** Change UTXO (remaining balance) */
9
+ changeUTXO: SerializedUTXO;
10
+ /** Leaf index of the change UTXO */
11
+ leafIndex: number;
12
+ /** New Merkle root after insertion */
13
+ root: Uint8Array;
14
+ };
15
+ /**
16
+ * Withdraw funds from the privacy pool.
17
+ *
18
+ * For withdrawals, we spend input UTXOs and create change output UTXOs.
19
+ * The publicAmount is negative (funds flowing out).
20
+ *
21
+ * @param withdrawAmount - Amount to withdraw in lamports/token units
22
+ * @param inputUTXOs - The UTXOs being spent
23
+ * @param changePubkey - UTXO public key for the change output
24
+ * @param inputTreeId - The tree ID where input UTXOs are located
25
+ * @param outputTreeId - The tree ID where change outputs will be inserted
26
+ */
27
+ export declare function withdraw<T extends Idl>(params: {
28
+ program: Program<T>;
29
+ relayer: Keypair;
30
+ recipient: PublicKey;
31
+ mintAddress: PublicKey;
32
+ inputUTXOs: [InputUTXO, InputUTXO];
33
+ changePubkey: bigint;
34
+ withdrawAmount: bigint;
35
+ fee: bigint;
36
+ refund: bigint;
37
+ root: Uint8Array;
38
+ inputTreeId: number;
39
+ outputTreeId: number;
40
+ tree: MerkleTree;
41
+ proofBuilder: TransactionProofBuilder;
42
+ /** When true, the fee is debited in addition to withdrawAmount. */
43
+ feeOnTop?: boolean;
44
+ deadline?: bigint;
45
+ /** Solana wallet key used to encrypt the change note for chain recovery. */
46
+ changeNoteRecipientWallet?: PublicKey | Uint8Array;
47
+ /** Prebuilt recovery payload. Takes precedence over changeNoteRecipientWallet. */
48
+ noteCiphers?: NoteCiphers | null;
49
+ }): Promise<WithdrawResult>;
50
+ /**
51
+ * Result of a private transfer operation.
52
+ */
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.withdraw = withdraw;
4
+ const web3_js_1 = require("@solana/web3.js");
5
+ const transaction_js_1 = require("../proofs/transaction.js");
6
+ const encoding_js_1 = require("../proofs/encoding.js");
7
+ const model_js_1 = require("../notes/model.js");
8
+ const transact_js_1 = require("./transact.js");
9
+ const poseidon_js_1 = require("../poseidon.js");
10
+ const compactNote_js_1 = require("../compactNote.js");
11
+ /**
12
+ * Withdraw funds from the privacy pool.
13
+ *
14
+ * For withdrawals, we spend input UTXOs and create change output UTXOs.
15
+ * The publicAmount is negative (funds flowing out).
16
+ *
17
+ * @param withdrawAmount - Amount to withdraw in lamports/token units
18
+ * @param inputUTXOs - The UTXOs being spent
19
+ * @param changePubkey - UTXO public key for the change output
20
+ * @param inputTreeId - The tree ID where input UTXOs are located
21
+ * @param outputTreeId - The tree ID where change outputs will be inserted
22
+ */
23
+ async function withdraw(params) {
24
+ const { program, relayer, recipient, mintAddress, inputUTXOs, changePubkey, withdrawAmount, fee, refund, root, inputTreeId, outputTreeId, tree, proofBuilder, feeOnTop = false, deadline = BigInt(Math.floor(Date.now() / 1000) + 600), changeNoteRecipientWallet, noteCiphers, } = params;
25
+ const totalInput = inputUTXOs[0].amount + inputUTXOs[1].amount;
26
+ const outflowAmount = feeOnTop ? withdrawAmount + fee : withdrawAmount;
27
+ const changeAmount = totalInput - outflowAmount;
28
+ if (withdrawAmount <= 0n) {
29
+ throw new Error("Withdrawal amount must be positive");
30
+ }
31
+ if (fee < 0n || refund < 0n || fee + refund > outflowAmount) {
32
+ throw new Error("Withdrawal fee and refund must fit within the public outflow");
33
+ }
34
+ if (changeAmount < 0n) {
35
+ throw new Error("Insufficient input balance for withdrawal");
36
+ }
37
+ const changeUTXO = (0, model_js_1.createUTXO)({
38
+ amount: changeAmount,
39
+ pubkey: changePubkey,
40
+ mintAddress,
41
+ });
42
+ const zeroUTXO = (0, model_js_1.createUTXO)({
43
+ amount: 0n,
44
+ pubkey: (0, model_js_1.generateKeypair)().publicKey,
45
+ mintAddress,
46
+ });
47
+ const outputUTXOs = [changeUTXO, zeroUTXO];
48
+ const extData = {
49
+ recipient,
50
+ relayer: relayer.publicKey,
51
+ fee,
52
+ refund,
53
+ claimant: web3_js_1.SystemProgram.programId,
54
+ };
55
+ // publicAmount is negative for withdrawals
56
+ const publicAmount = -outflowAmount;
57
+ const circuitInputs = (0, transaction_js_1.prepareTransactionInputs)({
58
+ inputUTXOs,
59
+ outputUTXOs,
60
+ root,
61
+ publicAmount,
62
+ extData,
63
+ mintAddress,
64
+ });
65
+ const rawProof = await proofBuilder(circuitInputs);
66
+ const proof = (0, encoding_js_1.encodeSnarkjsProofToTransactionProof)(rawProof);
67
+ const withdrawNoteCiphers = noteCiphers !== undefined
68
+ ? noteCiphers
69
+ : changeNoteRecipientWallet && changeAmount > 0n
70
+ ? (0, compactNote_js_1.createNoteCiphers)({
71
+ recipientWalletPubkey: changeNoteRecipientWallet instanceof web3_js_1.PublicKey
72
+ ? changeNoteRecipientWallet.toBytes()
73
+ : changeNoteRecipientWallet,
74
+ blinding: (0, poseidon_js_1.bigIntToBytesBE)(changeUTXO.blinding),
75
+ amount: changeAmount,
76
+ }, null)
77
+ : null;
78
+ await (0, transact_js_1.transact)({
79
+ program,
80
+ relayer,
81
+ recipient,
82
+ mintAddress,
83
+ root,
84
+ inputTreeId,
85
+ outputTreeId,
86
+ publicAmount,
87
+ inputNullifiers: circuitInputs.inputNullifiers,
88
+ outputCommitments: circuitInputs.outputCommitments,
89
+ extData,
90
+ proof,
91
+ deadline,
92
+ noteCiphers: withdrawNoteCiphers,
93
+ });
94
+ const { index: changeIdx } = tree.insert(changeUTXO.commitment);
95
+ const { root: newRoot } = tree.insert(zeroUTXO.commitment);
96
+ return {
97
+ changeUTXO,
98
+ leafIndex: changeIdx,
99
+ root: newRoot,
100
+ };
101
+ }
102
+ /**
103
+ * Result of a private transfer operation.
104
+ */