@veilo/sdk-core 0.3.3 → 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 (251) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +289 -1262
  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 +17 -912
  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 +128 -0
  32. package/dist/cjs/compactNote.js +191 -0
  33. package/dist/cjs/events.d.ts +1 -1
  34. package/dist/cjs/events.js +2 -2
  35. package/dist/cjs/idl/privacy_pool.d.ts +5 -0
  36. package/dist/cjs/idl/privacy_pool.js +15218 -0
  37. package/dist/cjs/index.d.ts +17 -13
  38. package/dist/cjs/index.js +43 -30
  39. package/dist/cjs/merkle.d.ts +13 -0
  40. package/dist/cjs/merkle.js +31 -8
  41. package/dist/cjs/notes/encryption.d.ts +41 -0
  42. package/dist/cjs/notes/encryption.js +75 -0
  43. package/dist/cjs/notes/index.d.ts +5 -0
  44. package/dist/cjs/notes/index.js +21 -0
  45. package/dist/cjs/notes/mailbox.d.ts +70 -0
  46. package/dist/cjs/notes/mailbox.js +164 -0
  47. package/dist/cjs/notes/model.d.ts +91 -0
  48. package/dist/cjs/notes/model.js +109 -0
  49. package/dist/cjs/notes/nullifier.d.ts +27 -0
  50. package/dist/cjs/notes/nullifier.js +45 -0
  51. package/dist/cjs/notes/recovery.d.ts +10 -0
  52. package/dist/cjs/notes/recovery.js +31 -0
  53. package/dist/cjs/program.d.ts +11 -0
  54. package/dist/cjs/program.js +26 -3
  55. package/dist/cjs/proof.d.ts +1 -183
  56. package/dist/cjs/proof.js +16 -290
  57. package/dist/cjs/proofs/encoding.d.ts +17 -0
  58. package/dist/cjs/proofs/encoding.js +72 -0
  59. package/dist/cjs/proofs/formatting.d.ts +6 -0
  60. package/dist/cjs/proofs/formatting.js +34 -0
  61. package/dist/cjs/proofs/index.d.ts +5 -0
  62. package/dist/cjs/proofs/index.js +21 -0
  63. package/dist/cjs/proofs/swap.d.ts +87 -0
  64. package/dist/cjs/proofs/swap.js +144 -0
  65. package/dist/cjs/proofs/transaction.d.ts +28 -0
  66. package/dist/cjs/proofs/transaction.js +110 -0
  67. package/dist/cjs/proofs/types.d.ts +70 -0
  68. package/dist/cjs/proofs/types.js +2 -0
  69. package/dist/cjs/prover.d.ts +4 -1
  70. package/dist/cjs/prover.js +12 -2
  71. package/dist/cjs/random.d.ts +16 -0
  72. package/dist/cjs/random.js +28 -0
  73. package/dist/cjs/relayer/client.d.ts +61 -0
  74. package/dist/cjs/relayer/client.js +151 -0
  75. package/dist/cjs/relayer/crypto.d.ts +5 -0
  76. package/dist/cjs/relayer/crypto.js +26 -0
  77. package/dist/cjs/relayer/encoding.d.ts +2 -0
  78. package/dist/cjs/relayer/encoding.js +23 -0
  79. package/dist/cjs/relayer/errors.d.ts +7 -0
  80. package/dist/cjs/relayer/errors.js +17 -0
  81. package/dist/cjs/relayer/index.d.ts +3 -0
  82. package/dist/cjs/relayer/index.js +19 -0
  83. package/dist/cjs/relayer/transport.d.ts +17 -0
  84. package/dist/cjs/relayer/transport.js +63 -0
  85. package/dist/cjs/relayer/types.d.ts +276 -0
  86. package/dist/cjs/relayer/types.js +5 -0
  87. package/dist/cjs/relayer.d.ts +1 -295
  88. package/dist/cjs/relayer.js +15 -243
  89. package/dist/cjs/shield/alt.d.ts +87 -0
  90. package/dist/cjs/shield/alt.js +194 -0
  91. package/dist/cjs/shield/computeBudget.d.ts +61 -0
  92. package/dist/cjs/shield/computeBudget.js +64 -0
  93. package/dist/cjs/shield/errors.d.ts +58 -0
  94. package/dist/cjs/shield/errors.js +121 -0
  95. package/dist/cjs/shield/finalize.d.ts +45 -0
  96. package/dist/cjs/shield/finalize.js +119 -0
  97. package/dist/cjs/shield/index.d.ts +35 -0
  98. package/dist/cjs/shield/index.js +68 -0
  99. package/dist/cjs/shield/ix.d.ts +54 -0
  100. package/dist/cjs/shield/ix.js +119 -0
  101. package/dist/cjs/shield/owner.d.ts +36 -0
  102. package/dist/cjs/shield/owner.js +127 -0
  103. package/dist/cjs/shield/ports.d.ts +43 -0
  104. package/dist/cjs/shield/ports.js +153 -0
  105. package/dist/cjs/shield/preflight.d.ts +30 -0
  106. package/dist/cjs/shield/preflight.js +154 -0
  107. package/dist/cjs/shield/shield.d.ts +68 -0
  108. package/dist/cjs/shield/shield.js +500 -0
  109. package/dist/cjs/shield/types.d.ts +202 -0
  110. package/dist/cjs/shield/types.js +2 -0
  111. package/dist/cjs/transactions/deposit.d.ts +94 -0
  112. package/dist/cjs/transactions/deposit.js +234 -0
  113. package/dist/cjs/transactions/index.d.ts +7 -0
  114. package/dist/cjs/transactions/index.js +26 -0
  115. package/dist/cjs/transactions/swap.d.ts +71 -0
  116. package/dist/cjs/transactions/swap.js +184 -0
  117. package/dist/cjs/transactions/transact.d.ts +34 -0
  118. package/dist/cjs/transactions/transact.js +146 -0
  119. package/dist/cjs/transactions/transfer.d.ts +51 -0
  120. package/dist/cjs/transactions/transfer.js +106 -0
  121. package/dist/cjs/transactions/withdraw.d.ts +52 -0
  122. package/dist/cjs/transactions/withdraw.js +104 -0
  123. package/dist/cjs/utxo.d.ts +1 -215
  124. package/dist/cjs/utxo.js +15 -391
  125. package/dist/esm/accounts/admin.d.ts +84 -0
  126. package/dist/esm/accounts/admin.js +165 -0
  127. package/dist/esm/accounts/errors.d.ts +6 -0
  128. package/dist/esm/accounts/errors.js +95 -0
  129. package/dist/esm/accounts/index.d.ts +4 -0
  130. package/dist/esm/accounts/index.js +4 -0
  131. package/dist/esm/accounts/pdas.d.ts +23 -0
  132. package/dist/esm/accounts/pdas.js +38 -0
  133. package/dist/esm/accounts/queries.d.ts +41 -0
  134. package/dist/esm/accounts/queries.js +88 -0
  135. package/dist/esm/client.d.ts +2 -0
  136. package/dist/esm/client.js +3 -887
  137. package/dist/esm/cloak/client.d.ts +28 -0
  138. package/dist/esm/cloak/client.js +64 -0
  139. package/dist/esm/cloak/errors.d.ts +13 -0
  140. package/dist/esm/cloak/errors.js +21 -0
  141. package/dist/esm/cloak/helpers.d.ts +6 -0
  142. package/dist/esm/cloak/helpers.js +31 -0
  143. package/dist/esm/cloak/index.d.ts +6 -0
  144. package/dist/esm/cloak/index.js +6 -0
  145. package/dist/esm/cloak/polling.d.ts +7 -0
  146. package/dist/esm/cloak/polling.js +63 -0
  147. package/dist/esm/cloak/transport.d.ts +15 -0
  148. package/dist/esm/cloak/transport.js +115 -0
  149. package/dist/esm/cloak/types.d.ts +188 -0
  150. package/dist/esm/cloak/types.js +4 -0
  151. package/dist/esm/cloak.d.ts +1 -0
  152. package/dist/esm/cloak.js +2 -0
  153. package/dist/esm/compactNote.d.ts +128 -0
  154. package/dist/esm/compactNote.js +179 -0
  155. package/dist/esm/config.d.ts +82 -0
  156. package/dist/esm/events.d.ts +77 -0
  157. package/dist/esm/events.js +1 -1
  158. package/dist/esm/idl/privacy_pool.d.ts +5 -0
  159. package/dist/esm/idl/privacy_pool.js +15216 -0
  160. package/dist/esm/index.d.ts +17 -0
  161. package/dist/esm/index.js +20 -11
  162. package/dist/esm/merkle.d.ts +77 -0
  163. package/dist/esm/merkle.js +23 -1
  164. package/dist/esm/notes/encryption.d.ts +41 -0
  165. package/dist/esm/notes/encryption.js +67 -0
  166. package/dist/esm/notes/index.d.ts +5 -0
  167. package/dist/esm/notes/index.js +5 -0
  168. package/dist/esm/notes/mailbox.d.ts +70 -0
  169. package/dist/esm/notes/mailbox.js +154 -0
  170. package/dist/esm/notes/model.d.ts +91 -0
  171. package/dist/esm/notes/model.js +99 -0
  172. package/dist/esm/notes/nullifier.d.ts +27 -0
  173. package/dist/esm/notes/nullifier.js +40 -0
  174. package/dist/esm/notes/recovery.d.ts +10 -0
  175. package/dist/esm/notes/recovery.js +28 -0
  176. package/dist/esm/package.json +1 -0
  177. package/dist/esm/poseidon.d.ts +29 -0
  178. package/dist/esm/program.d.ts +37 -0
  179. package/dist/esm/program.js +23 -1
  180. package/dist/esm/proof.d.ts +1 -0
  181. package/dist/esm/proof.js +2 -281
  182. package/dist/esm/proofs/encoding.d.ts +17 -0
  183. package/dist/esm/proofs/encoding.js +68 -0
  184. package/dist/esm/proofs/formatting.d.ts +6 -0
  185. package/dist/esm/proofs/formatting.js +31 -0
  186. package/dist/esm/proofs/index.d.ts +5 -0
  187. package/dist/esm/proofs/index.js +5 -0
  188. package/dist/esm/proofs/swap.d.ts +87 -0
  189. package/dist/esm/proofs/swap.js +138 -0
  190. package/dist/esm/proofs/transaction.d.ts +28 -0
  191. package/dist/esm/proofs/transaction.js +105 -0
  192. package/dist/esm/proofs/types.d.ts +70 -0
  193. package/dist/esm/proofs/types.js +1 -0
  194. package/dist/esm/prover.d.ts +57 -0
  195. package/dist/esm/prover.js +10 -1
  196. package/dist/esm/random.d.ts +16 -0
  197. package/dist/esm/random.js +21 -0
  198. package/dist/esm/relayer/client.d.ts +61 -0
  199. package/dist/esm/relayer/client.js +144 -0
  200. package/dist/esm/relayer/crypto.d.ts +5 -0
  201. package/dist/esm/relayer/crypto.js +20 -0
  202. package/dist/esm/relayer/encoding.d.ts +2 -0
  203. package/dist/esm/relayer/encoding.js +19 -0
  204. package/dist/esm/relayer/errors.d.ts +7 -0
  205. package/dist/esm/relayer/errors.js +13 -0
  206. package/dist/esm/relayer/index.d.ts +3 -0
  207. package/dist/esm/relayer/index.js +3 -0
  208. package/dist/esm/relayer/transport.d.ts +17 -0
  209. package/dist/esm/relayer/transport.js +59 -0
  210. package/dist/esm/relayer/types.d.ts +276 -0
  211. package/dist/esm/relayer/types.js +4 -0
  212. package/dist/esm/relayer.d.ts +1 -0
  213. package/dist/esm/relayer.js +2 -238
  214. package/dist/esm/retry.d.ts +32 -0
  215. package/dist/esm/shield/alt.d.ts +87 -0
  216. package/dist/esm/shield/alt.js +186 -0
  217. package/dist/esm/shield/computeBudget.d.ts +61 -0
  218. package/dist/esm/shield/computeBudget.js +61 -0
  219. package/dist/esm/shield/errors.d.ts +58 -0
  220. package/dist/esm/shield/errors.js +115 -0
  221. package/dist/esm/shield/finalize.d.ts +45 -0
  222. package/dist/esm/shield/finalize.js +83 -0
  223. package/dist/esm/shield/index.d.ts +35 -0
  224. package/dist/esm/shield/index.js +32 -0
  225. package/dist/esm/shield/ix.d.ts +54 -0
  226. package/dist/esm/shield/ix.js +82 -0
  227. package/dist/esm/shield/owner.d.ts +36 -0
  228. package/dist/esm/shield/owner.js +123 -0
  229. package/dist/esm/shield/ports.d.ts +43 -0
  230. package/dist/esm/shield/ports.js +147 -0
  231. package/dist/esm/shield/preflight.d.ts +30 -0
  232. package/dist/esm/shield/preflight.js +151 -0
  233. package/dist/esm/shield/shield.d.ts +68 -0
  234. package/dist/esm/shield/shield.js +493 -0
  235. package/dist/esm/shield/types.d.ts +202 -0
  236. package/dist/esm/shield/types.js +1 -0
  237. package/dist/esm/transactions/deposit.d.ts +94 -0
  238. package/dist/esm/transactions/deposit.js +198 -0
  239. package/dist/esm/transactions/index.d.ts +7 -0
  240. package/dist/esm/transactions/index.js +7 -0
  241. package/dist/esm/transactions/swap.d.ts +71 -0
  242. package/dist/esm/transactions/swap.js +144 -0
  243. package/dist/esm/transactions/transact.d.ts +34 -0
  244. package/dist/esm/transactions/transact.js +110 -0
  245. package/dist/esm/transactions/transfer.d.ts +51 -0
  246. package/dist/esm/transactions/transfer.js +103 -0
  247. package/dist/esm/transactions/withdraw.d.ts +52 -0
  248. package/dist/esm/transactions/withdraw.js +101 -0
  249. package/dist/esm/utxo.d.ts +1 -0
  250. package/dist/esm/utxo.js +2 -372
  251. package/package.json +111 -15
@@ -0,0 +1,184 @@
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.getSwapExecutorPda = getSwapExecutorPda;
37
+ exports.fundNativeSource = fundNativeSource;
38
+ exports.buildTransactSwapInstruction = buildTransactSwapInstruction;
39
+ exports.buildPrivateSwapInstructions = buildPrivateSwapInstructions;
40
+ exports.transactSwap = transactSwap;
41
+ const anchor = __importStar(require("@coral-xyz/anchor"));
42
+ const web3_js_1 = require("@solana/web3.js");
43
+ const spl_token_1 = require("@solana/spl-token");
44
+ const config_js_1 = require("../config.js");
45
+ const retry_js_1 = require("../retry.js");
46
+ const pdas_js_1 = require("../accounts/pdas.js");
47
+ const { BN } = anchor;
48
+ /** Seeds: ["swap_executor", source_mint, dest_mint, nullifier_0, relayer]. */
49
+ function getSwapExecutorPda(programId, sourceMint, destMint, inputNullifier0, relayer) {
50
+ const [executor] = web3_js_1.PublicKey.findProgramAddressSync([
51
+ Buffer.from("swap_executor"),
52
+ sourceMint.toBuffer(),
53
+ destMint.toBuffer(),
54
+ inputNullifier0,
55
+ relayer.toBuffer(),
56
+ ], programId);
57
+ return executor;
58
+ }
59
+ /** Build `fund_native_source`. It must immediately precede `transact_swap`. */
60
+ async function fundNativeSource(params) {
61
+ const { program, relayer, sourceMint, destMint, inputNullifier0, swapAmount, sourceMintAccount = spl_token_1.NATIVE_MINT, } = params;
62
+ const { vault: sourceVault, config: sourceConfig } = (0, pdas_js_1.getPoolPdas)(program.programId, sourceMint);
63
+ const executor = getSwapExecutorPda(program.programId, sourceMint, destMint, inputNullifier0, relayer.publicKey);
64
+ const executorSourceToken = await (0, spl_token_1.getAssociatedTokenAddress)(sourceMintAccount, executor, true);
65
+ return program.methods
66
+ .fundNativeSource(sourceMint, destMint, Array.from(inputNullifier0), new BN(swapAmount.toString()))
67
+ .accountsStrict({
68
+ executor,
69
+ executorSourceToken,
70
+ sourceVault,
71
+ sourceConfig,
72
+ sourceMintAccount,
73
+ relayer: relayer.publicKey,
74
+ instructionsSysvar: web3_js_1.SYSVAR_INSTRUCTIONS_PUBKEY,
75
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
76
+ systemProgram: web3_js_1.SystemProgram.programId,
77
+ associatedTokenProgram: spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID,
78
+ })
79
+ .instruction();
80
+ }
81
+ function encodeNoteCiphers(noteCiphers) {
82
+ return noteCiphers
83
+ ? {
84
+ note0EphemeralKey: Array.from(noteCiphers.note0EphemeralKey),
85
+ note0Encrypted: Array.from(noteCiphers.note0Encrypted),
86
+ note0ViewTag: noteCiphers.note0ViewTag,
87
+ note1EphemeralKey: Array.from(noteCiphers.note1EphemeralKey),
88
+ note1Encrypted: Array.from(noteCiphers.note1Encrypted),
89
+ note1ViewTag: noteCiphers.note1ViewTag,
90
+ }
91
+ : null;
92
+ }
93
+ /** Build the current IDL's `transact_swap` instruction without submitting it. */
94
+ async function buildTransactSwapInstruction(params) {
95
+ const { program, relayer, sourceMint, destMint, sourceRoot, sourceTreeId, destTreeId, inputNullifiers, outputCommitments, proof, swapParams, swapAmount, swapData, extData, noteCiphers = null, sourceVaultTokenAccount, sourceMintAccount, destVaultTokenAccount, destMintAccount, relayerTokenAccount, swapProgram, jupiterEventAuthority, remainingAccounts = [], } = params;
96
+ if (!extData.relayer.equals(relayer.publicKey)) {
97
+ throw new Error("extData.relayer must match the relayer account");
98
+ }
99
+ if (swapParams.deadline <= 0n) {
100
+ throw new Error("swapParams.deadline must be a positive Unix timestamp");
101
+ }
102
+ if (swapParams.swapDataHash.length !== 32) {
103
+ throw new Error("swapParams.swapDataHash must be 32 bytes");
104
+ }
105
+ const { config: sourceConfig, vault: sourceVault, nullifiers: sourceNullifiers, } = (0, pdas_js_1.getPoolPdas)(program.programId, sourceMint);
106
+ const { config: destConfig, vault: destVault } = (0, pdas_js_1.getPoolPdas)(program.programId, destMint);
107
+ const globalConfig = (0, pdas_js_1.getGlobalConfigPda)(program.programId);
108
+ const sourceTree = (0, pdas_js_1.getNoteTreePda)(program.programId, sourceMint, sourceTreeId);
109
+ const destTree = (0, pdas_js_1.getNoteTreePda)(program.programId, destMint, destTreeId);
110
+ const sourceNullifierMarker0 = (0, pdas_js_1.getNullifierMarkerPda)(program.programId, sourceMint, inputNullifiers[0]);
111
+ const sourceNullifierMarker1 = (0, pdas_js_1.getNullifierMarkerPda)(program.programId, sourceMint, inputNullifiers[1]);
112
+ const executor = getSwapExecutorPda(program.programId, sourceMint, destMint, inputNullifiers[0], relayer.publicKey);
113
+ const executorSourceToken = await (0, spl_token_1.getAssociatedTokenAddress)(sourceMintAccount, executor, true);
114
+ const executorDestToken = await (0, spl_token_1.getAssociatedTokenAddress)(destMintAccount, executor, true);
115
+ let method = program.methods
116
+ .transactSwap(sourceTreeId, sourceMint, Array.from(inputNullifiers[0]), Array.from(inputNullifiers[1]), destTreeId, destMint, { proofA: proof.proofA, proofB: proof.proofB, proofC: proof.proofC }, Array.from(sourceRoot), Array.from(outputCommitments[0]), Array.from(outputCommitments[1]), {
117
+ minAmountOut: new BN(swapParams.minAmountOut.toString()),
118
+ deadline: new BN(swapParams.deadline.toString()),
119
+ destAmount: new BN(swapParams.destAmount.toString()),
120
+ swapDataHash: Array.from(swapParams.swapDataHash),
121
+ }, new BN(swapAmount.toString()), Buffer.from(swapData), {
122
+ recipient: extData.recipient,
123
+ relayer: extData.relayer,
124
+ fee: new BN(extData.fee.toString()),
125
+ refund: new BN(extData.refund.toString()),
126
+ claimant: extData.claimant,
127
+ }, encodeNoteCiphers(noteCiphers))
128
+ .accountsStrict({
129
+ sourceConfig,
130
+ globalConfig,
131
+ sourceVault,
132
+ sourceTree,
133
+ sourceNullifiers,
134
+ sourceNullifierMarker0,
135
+ sourceNullifierMarker1,
136
+ sourceVaultTokenAccount,
137
+ sourceMintAccount,
138
+ destConfig,
139
+ destVault,
140
+ destTree,
141
+ destVaultTokenAccount,
142
+ destMintAccount,
143
+ executor,
144
+ executorSourceToken,
145
+ executorDestToken,
146
+ relayer: relayer.publicKey,
147
+ relayerTokenAccount,
148
+ swapProgram,
149
+ jupiterEventAuthority,
150
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
151
+ systemProgram: web3_js_1.SystemProgram.programId,
152
+ associatedTokenProgram: spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID,
153
+ });
154
+ // Jupiter account order and duplicates are part of the CPI contract.
155
+ method = method.remainingAccounts(remainingAccounts);
156
+ return method.instruction();
157
+ }
158
+ /** Build the atomic instruction sequence, including native-source funding. */
159
+ async function buildPrivateSwapInstructions(params) {
160
+ const instructions = [];
161
+ if (params.sourceMint.equals(config_js_1.NATIVE_SOL_MINT)) {
162
+ instructions.push(await fundNativeSource({
163
+ program: params.program,
164
+ relayer: params.relayer,
165
+ sourceMint: params.sourceMint,
166
+ destMint: params.destMint,
167
+ inputNullifier0: params.inputNullifiers[0],
168
+ swapAmount: params.swapAmount,
169
+ sourceMintAccount: params.sourceMintAccount,
170
+ }));
171
+ }
172
+ instructions.push(await buildTransactSwapInstruction(params));
173
+ return instructions;
174
+ }
175
+ /**
176
+ * Submit the parity-correct instructions as a legacy transaction. For Jupiter
177
+ * routes, prefer `buildPrivateSwapInstructions` and compile v0 with route ALTs.
178
+ */
179
+ async function transactSwap(params) {
180
+ const instructions = await buildPrivateSwapInstructions(params);
181
+ const transaction = new web3_js_1.Transaction().add(...instructions);
182
+ const provider = params.program.provider;
183
+ return (0, retry_js_1.withRpcRetry)(() => provider.sendAndConfirm(transaction, [params.relayer]));
184
+ }
@@ -0,0 +1,34 @@
1
+ import type { Program, Idl } from "@coral-xyz/anchor";
2
+ import { Keypair, PublicKey } from "@solana/web3.js";
3
+ import type { ExtData, TransactionProofStruct } from "../proofs/types.js";
4
+ import type { NoteCiphers } from "../compactNote.js";
5
+ /**
6
+ * Execute a transaction on the privacy pool.
7
+ * This is the low-level function that calls the on-chain `transact` instruction.
8
+ *
9
+ * @param publicAmount - Positive for deposits, negative for withdrawals, 0 for transfers
10
+ * @param inputTreeId - The tree ID where input UTXOs are located
11
+ * @param outputTreeId - The tree ID where output commitments will be inserted
12
+ */
13
+ export declare function transact<T extends Idl>(params: {
14
+ program: Program<T>;
15
+ relayer: Keypair;
16
+ recipient: PublicKey;
17
+ mintAddress: PublicKey;
18
+ root: Uint8Array;
19
+ inputTreeId: number;
20
+ outputTreeId: number;
21
+ publicAmount: bigint;
22
+ inputNullifiers: [Uint8Array, Uint8Array];
23
+ outputCommitments: [Uint8Array, Uint8Array];
24
+ extData: ExtData;
25
+ proof: TransactionProofStruct;
26
+ /** Unix timestamp after which the tx is invalid. Defaults to 10 minutes from build time. */
27
+ deadline?: bigint;
28
+ /** Optional compact recovery payload emitted with the two output commitments. */
29
+ noteCiphers?: NoteCiphers | null;
30
+ vaultTokenAccount?: PublicKey;
31
+ userTokenAccount?: PublicKey;
32
+ recipientTokenAccount?: PublicKey;
33
+ relayerTokenAccount?: PublicKey;
34
+ }): Promise<string>;
@@ -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
+ */