@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,30 @@
1
+ import { Connection, PublicKey } from "@solana/web3.js";
2
+ import type { PreflightOptions, ShieldCachePort } from "./types.js";
3
+ /**
4
+ * Checks that run before the prover.
5
+ *
6
+ * Proving costs 10–30 seconds. Every check here is a single RPC call, and each
7
+ * one pre-empts an on-chain failure whose message tells the user nothing they
8
+ * can act on. The delegate check is the clearest example: the program requires
9
+ * `user_token.delegate.is_none()`, so anyone who ever approved a DEX has a
10
+ * permanently broken deposit path that reports only "Invalid token account
11
+ * authority" — with no hint that revoking a delegate would fix it.
12
+ *
13
+ * These are advisory in the sense that the chain enforces them anyway. They are
14
+ * not advisory in the sense that skipping them produces a materially worse
15
+ * product.
16
+ */
17
+ export declare function preflightShield(params: {
18
+ connection: Connection;
19
+ amount: bigint;
20
+ mint: PublicKey;
21
+ signer: {
22
+ publicKey: PublicKey;
23
+ tokenAccount: PublicKey;
24
+ };
25
+ programId?: PublicKey;
26
+ options?: PreflightOptions;
27
+ cache?: ShieldCachePort;
28
+ computeUnitLimit?: number;
29
+ computeUnitPriceMicroLamports?: number;
30
+ }): Promise<void>;
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.preflightShield = preflightShield;
4
+ const spl_token_1 = require("@solana/spl-token");
5
+ const pdas_js_1 = require("../accounts/pdas.js");
6
+ const program_js_1 = require("../program.js");
7
+ const config_js_1 = require("../config.js");
8
+ const errors_js_1 = require("./errors.js");
9
+ const computeBudget_js_1 = require("./computeBudget.js");
10
+ /**
11
+ * Checks that run before the prover.
12
+ *
13
+ * Proving costs 10–30 seconds. Every check here is a single RPC call, and each
14
+ * one pre-empts an on-chain failure whose message tells the user nothing they
15
+ * can act on. The delegate check is the clearest example: the program requires
16
+ * `user_token.delegate.is_none()`, so anyone who ever approved a DEX has a
17
+ * permanently broken deposit path that reports only "Invalid token account
18
+ * authority" — with no hint that revoking a delegate would fix it.
19
+ *
20
+ * These are advisory in the sense that the chain enforces them anyway. They are
21
+ * not advisory in the sense that skipping them produces a materially worse
22
+ * product.
23
+ */
24
+ async function preflightShield(params) {
25
+ const { connection, amount, mint, signer, programId = program_js_1.PRIVACY_POOL_PROGRAM_ID, options = {}, } = params;
26
+ const isToken = !mint.equals(config_js_1.NATIVE_SOL_MINT);
27
+ // --- Pool state ------------------------------------------------------------
28
+ if (!options.skipPoolState) {
29
+ const program = (0, program_js_1.createReadonlyVeiloProgram)(connection);
30
+ const { config } = (0, pdas_js_1.getPoolPdas)(programId, mint);
31
+ let cfg;
32
+ try {
33
+ cfg = await program.account.privacyConfig.fetch(config);
34
+ }
35
+ catch (e) {
36
+ throw new errors_js_1.ShieldError("POOL_NOT_FOUND", `No privacy pool exists for mint ${mint.toBase58()}.`, { context: { mint: mint.toBase58(), config: config.toBase58() }, cause: e });
37
+ }
38
+ if (cfg.paused) {
39
+ throw new errors_js_1.ShieldError("POOL_PAUSED", "The pool is paused. Try again later.");
40
+ }
41
+ const min = BigInt(cfg.minDepositAmount?.toString() ?? "0");
42
+ const max = BigInt(cfg.maxDepositAmount?.toString() ?? "0");
43
+ if (min > 0n && amount < min) {
44
+ throw new errors_js_1.ShieldError("AMOUNT_BELOW_MINIMUM", `Amount ${amount} is below the pool minimum of ${min}.`, { context: { amount: amount.toString(), minimum: min.toString() } });
45
+ }
46
+ if (max > 0n && amount > max) {
47
+ throw new errors_js_1.ShieldError("AMOUNT_ABOVE_MAXIMUM", `Amount ${amount} exceeds the pool maximum of ${max}.`, { context: { amount: amount.toString(), maximum: max.toString() } });
48
+ }
49
+ }
50
+ // --- Source token account (SPL only) --------------------------------------
51
+ if (isToken && !options.skipTokenAccount) {
52
+ let account;
53
+ try {
54
+ account = await (0, spl_token_1.getAccount)(connection, signer.tokenAccount);
55
+ }
56
+ catch (e) {
57
+ if (e instanceof spl_token_1.TokenAccountNotFoundError || /could not find/i.test(String(e))) {
58
+ // Deliberately no "create the ATA" remedy: an ATA that does not exist
59
+ // holds zero tokens, so creating it would only move the failure to
60
+ // INSUFFICIENT_TOKEN_BALANCE. Say the true thing instead.
61
+ throw new errors_js_1.ShieldError("TOKEN_ACCOUNT_MISSING", `The signer has no token account for ${mint.toBase58()}, so there is nothing to shield.`, { context: { tokenAccount: signer.tokenAccount.toBase58() }, cause: e });
62
+ }
63
+ throw e;
64
+ }
65
+ if (!account.mint.equals(mint)) {
66
+ throw new errors_js_1.ShieldError("TOKEN_ACCOUNT_WRONG_MINT", `Token account ${signer.tokenAccount.toBase58()} holds ${account.mint.toBase58()}, not ${mint.toBase58()}.`, { context: { expected: mint.toBase58(), actual: account.mint.toBase58() } });
67
+ }
68
+ if (!account.owner.equals(signer.publicKey)) {
69
+ throw new errors_js_1.ShieldError("TOKEN_ACCOUNT_WRONG_OWNER", `Token account ${signer.tokenAccount.toBase58()} is owned by ${account.owner.toBase58()}, ` +
70
+ `not by the signing wallet. The program requires the signer to own the source account outright.`, {
71
+ context: {
72
+ tokenAccount: signer.tokenAccount.toBase58(),
73
+ owner: account.owner.toBase58(),
74
+ signer: signer.publicKey.toBase58(),
75
+ },
76
+ });
77
+ }
78
+ if (account.isFrozen) {
79
+ throw new errors_js_1.ShieldError("TOKEN_ACCOUNT_FROZEN", `Token account ${signer.tokenAccount.toBase58()} is frozen.`, { context: { tokenAccount: signer.tokenAccount.toBase58() } });
80
+ }
81
+ // The program checks `delegate.is_none()`, NOT the delegated amount — so a
82
+ // stale delegate with zero allowance still fails. This is the single most
83
+ // common avoidable failure on this path, and it is entirely fixable.
84
+ if (account.delegate) {
85
+ throw new errors_js_1.ShieldError("TOKEN_ACCOUNT_DELEGATED", `Token account ${signer.tokenAccount.toBase58()} has an active delegate ` +
86
+ `(${account.delegate.toBase58()}). The pool rejects deposits from delegated ` +
87
+ `accounts even when the delegated amount is zero. Revoke the delegate, then shield.`, {
88
+ context: {
89
+ tokenAccount: signer.tokenAccount.toBase58(),
90
+ delegate: account.delegate.toBase58(),
91
+ delegatedAmount: account.delegatedAmount.toString(),
92
+ },
93
+ remedy: {
94
+ description: `Revoke the delegate on ${signer.tokenAccount.toBase58()}`,
95
+ instructions: [
96
+ (0, spl_token_1.createRevokeInstruction)(signer.tokenAccount, signer.publicKey),
97
+ ],
98
+ },
99
+ });
100
+ }
101
+ if (account.amount < amount) {
102
+ throw new errors_js_1.ShieldError("INSUFFICIENT_TOKEN_BALANCE", `Token account holds ${account.amount} but ${amount} is required.`, { context: { balance: account.amount.toString(), required: amount.toString() } });
103
+ }
104
+ // The vault's ATA must already exist — the program requires the canonical
105
+ // one and will not create it.
106
+ const { vault } = (0, pdas_js_1.getPoolPdas)(programId, mint);
107
+ const vaultAta = await (0, spl_token_1.getAssociatedTokenAddress)(mint, vault, true);
108
+ const vaultInfo = await connection.getAccountInfo(vaultAta);
109
+ if (!vaultInfo) {
110
+ throw new errors_js_1.ShieldError("VAULT_ATA_MISSING", `The pool vault has no associated token account for ${mint.toBase58()}. ` +
111
+ `This is a pool provisioning issue, not something the signer can fix.`, { context: { vault: vault.toBase58(), vaultAta: vaultAta.toBase58() } });
112
+ }
113
+ }
114
+ // --- Signer balance --------------------------------------------------------
115
+ if (!options.skipBalance) {
116
+ const rentPer = await cachedRent(connection, params.cache);
117
+ const rent = BigInt(rentPer) * BigInt(computeBudget_js_1.NULLIFIER_MARKERS_PER_TRANSACT);
118
+ const computeUnitLimit = params.computeUnitLimit ?? computeBudget_js_1.SHIELD_COMPUTE_UNIT_LIMIT;
119
+ const computeUnitPriceMicroLamports = params.computeUnitPriceMicroLamports ?? computeBudget_js_1.SHIELD_COMPUTE_UNIT_PRICE_MICRO_LAMPORTS;
120
+ const priorityFee = (BigInt(computeUnitLimit) * BigInt(computeUnitPriceMicroLamports)) /
121
+ 1000000n;
122
+ const baseFee = 5000n;
123
+ // The signer pays the marker rent regardless of the mint — it is SOL either
124
+ // way, and it is burned, not refunded.
125
+ const required = rent + priorityFee + baseFee + (isToken ? 0n : amount);
126
+ const balance = BigInt(await connection.getBalance(signer.publicKey));
127
+ if (balance < required) {
128
+ throw new errors_js_1.ShieldError("INSUFFICIENT_SOL", `The signing wallet has ${balance} lamports but needs ${required} ` +
129
+ `(${isToken ? "" : `${amount} shielded + `}${rent} nullifier-marker rent + ` +
130
+ `${priorityFee + baseFee} fees). Note that the marker rent is burned, not refunded, ` +
131
+ `and the program forces it onto the signer — it cannot be sponsored.`, {
132
+ context: {
133
+ balance: balance.toString(),
134
+ required: required.toString(),
135
+ breakdown: {
136
+ amount: isToken ? "0" : amount.toString(),
137
+ nullifierMarkerRent: rent.toString(),
138
+ priorityFee: priorityFee.toString(),
139
+ baseFee: baseFee.toString(),
140
+ },
141
+ },
142
+ });
143
+ }
144
+ }
145
+ }
146
+ async function cachedRent(connection, cache) {
147
+ const key = `rent:${computeBudget_js_1.NULLIFIER_MARKER_ACCOUNT_BYTES}`;
148
+ const hit = await cache?.get(key);
149
+ if (hit !== undefined)
150
+ return hit;
151
+ const value = await connection.getMinimumBalanceForRentExemption(computeBudget_js_1.NULLIFIER_MARKER_ACCOUNT_BYTES);
152
+ await cache?.set(key, value, 60 * 60000);
153
+ return value;
154
+ }
@@ -0,0 +1,68 @@
1
+ import { AddressLookupTableAccount, Connection } from "@solana/web3.js";
2
+ import { bytesToBigIntBE, BN254_FR_MODULUS } from "../poseidon.js";
3
+ import type { ShieldParams, ShieldProofCache, ShieldResult } from "./types.js";
4
+ /**
5
+ * Build an unsigned transaction that shields public funds into the privacy pool.
6
+ *
7
+ * ## The contract
8
+ *
9
+ * This function builds. It does not sign, submit, confirm, or retry — those
10
+ * belong to whoever holds the key, exactly as with Jupiter's `/swap`. The
11
+ * returned `transaction` is unsigned; the caller signs it with whatever wallet
12
+ * they have and broadcasts it themselves.
13
+ *
14
+ * ## Why this can be handed to a third party
15
+ *
16
+ * Three properties make it safe to build a shield on behalf of a signer you do
17
+ * not control, and to shield to an owner who is not the signer:
18
+ *
19
+ * 1. **Deposits are permissionless.** The program gates its relayer allowlist
20
+ * to `public_amount <= 0`, so any wallet can sign a deposit.
21
+ * 2. **No secrets are involved in building.** The proof for a deposit has no
22
+ * real inputs, and the output commitment binds only the recipient's *public*
23
+ * keys.
24
+ * 3. **The note rides on-chain.** `note_ciphers` travels inside the instruction,
25
+ * so the recipient can find the note by scanning even if the platform that
26
+ * submitted it never says a word.
27
+ *
28
+ * ## What the signer unavoidably pays
29
+ *
30
+ * The signer is the fee payer, the funding source, and the payer of two
31
+ * `NullifierMarker` rents (~0.00192 SOL, permanently burned — the program
32
+ * hardcodes `payer = relayer` on both). A wallet with zero SOL cannot shield
33
+ * through this path no matter who submits the transaction. Fee sponsorship is
34
+ * not achievable here: a second signature costs ~96 bytes against a budget with
35
+ * ~69 to spare, and would not cover the rent anyway.
36
+ */
37
+ export declare function shield(params: ShieldParams): Promise<ShieldResult>;
38
+ /**
39
+ * Re-assemble a shield with a fresh blockhash and deadline, reusing the proof.
40
+ *
41
+ * The Groth16 proof commits to the root, the public amount, `ext_data_hash`, the
42
+ * mint, the nullifiers and the commitments — none of which is time-dependent.
43
+ * `deadline` is a positional instruction argument, outside `ext_data_hash` and
44
+ * therefore outside the proof, so it can be refreshed too. That last part
45
+ * matters: a shield built at T and signed at T+59min needs a new deadline, not
46
+ * just a new blockhash.
47
+ *
48
+ * Costs one `getLatestBlockhash` and a message compile — no proving, no
49
+ * Poseidon, no account resolution.
50
+ *
51
+ * Does NOT recover from `ROOT_STALE`: a stale root invalidates the proof, so
52
+ * that case needs a fresh `shield()` call.
53
+ */
54
+ export declare function rebuild(result: ShieldResult, opts?: {
55
+ connection?: Connection;
56
+ alt?: AddressLookupTableAccount;
57
+ blockhash?: {
58
+ blockhash: string;
59
+ lastValidBlockHeight: number;
60
+ };
61
+ deadlineSeconds?: number;
62
+ computeUnitPriceMicroLamports?: number;
63
+ }): Promise<ShieldResult>;
64
+ /** Serialize a proof cache for transport between processes. Contains no secrets. */
65
+ export declare function serializeProofCache(cache: ShieldProofCache): string;
66
+ export declare function deserializeProofCache(json: string): ShieldProofCache;
67
+ /** Re-exported for callers that want the raw field arithmetic. */
68
+ export { bytesToBigIntBE, BN254_FR_MODULUS };