@veilo/sdk-core 0.5.0 → 0.7.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 (240) hide show
  1. package/README.md +282 -18
  2. package/accounts.d.ts +2 -0
  3. package/accounts.js +3 -0
  4. package/cloak.d.ts +2 -0
  5. package/cloak.js +3 -0
  6. package/config.d.ts +2 -0
  7. package/config.js +3 -0
  8. package/dist/cjs/events/index.d.ts +6 -0
  9. package/dist/cjs/events/index.js +22 -0
  10. package/dist/cjs/events/parsing.d.ts +25 -0
  11. package/dist/cjs/events/parsing.js +158 -0
  12. package/dist/cjs/events/position.d.ts +26 -0
  13. package/dist/cjs/events/position.js +53 -0
  14. package/dist/cjs/events/recovery.d.ts +87 -0
  15. package/dist/cjs/events/recovery.js +281 -0
  16. package/dist/cjs/events/scanning.d.ts +35 -0
  17. package/dist/cjs/events/scanning.js +98 -0
  18. package/dist/cjs/events/tree.d.ts +27 -0
  19. package/dist/cjs/events/tree.js +63 -0
  20. package/dist/cjs/events/types.d.ts +39 -0
  21. package/dist/cjs/events/types.js +2 -0
  22. package/dist/cjs/events.d.ts +1 -77
  23. package/dist/cjs/events.js +6 -154
  24. package/dist/cjs/identity/encoding.d.ts +9 -0
  25. package/dist/cjs/identity/encoding.js +85 -0
  26. package/dist/cjs/identity/index.d.ts +4 -0
  27. package/dist/cjs/identity/index.js +20 -0
  28. package/dist/cjs/identity/noteKey.d.ts +33 -0
  29. package/dist/cjs/identity/noteKey.js +97 -0
  30. package/dist/cjs/identity/spending.d.ts +18 -0
  31. package/dist/cjs/identity/spending.js +46 -0
  32. package/dist/cjs/identity/viewKey.d.ts +38 -0
  33. package/dist/cjs/identity/viewKey.js +105 -0
  34. package/dist/cjs/idl/index.d.ts +18 -0
  35. package/dist/cjs/idl/index.js +24 -0
  36. package/dist/cjs/idl/privacy_pool.json +9907 -9907
  37. package/dist/cjs/idl/privacy_pool_legacy.d.ts +5 -0
  38. package/dist/cjs/idl/privacy_pool_legacy.js +3307 -0
  39. package/dist/cjs/idl/privacy_pool_legacy.json +2302 -0
  40. package/dist/cjs/idl/privacy_pool_legacy2.d.ts +5 -0
  41. package/dist/cjs/idl/privacy_pool_legacy2.js +3397 -0
  42. package/dist/cjs/idl/privacy_pool_legacy2.json +2376 -0
  43. package/dist/cjs/index.d.ts +8 -3
  44. package/dist/cjs/index.js +12 -2
  45. package/dist/cjs/notes/amount.d.ts +2 -0
  46. package/dist/cjs/notes/amount.js +21 -0
  47. package/dist/cjs/notes/index.d.ts +4 -0
  48. package/dist/cjs/notes/index.js +4 -0
  49. package/dist/cjs/notes/recovery.d.ts +16 -6
  50. package/dist/cjs/notes/recovery.js +33 -16
  51. package/dist/cjs/notes/scan.d.ts +74 -0
  52. package/dist/cjs/notes/scan.js +110 -0
  53. package/dist/cjs/notes/selection.d.ts +133 -0
  54. package/dist/cjs/notes/selection.js +260 -0
  55. package/dist/cjs/notes/spent.d.ts +60 -0
  56. package/dist/cjs/notes/spent.js +101 -0
  57. package/dist/cjs/perps/constants.d.ts +16 -0
  58. package/dist/cjs/perps/constants.js +52 -0
  59. package/dist/cjs/perps/index.d.ts +5 -0
  60. package/dist/cjs/perps/index.js +21 -0
  61. package/dist/cjs/perps/keys.d.ts +16 -0
  62. package/dist/cjs/perps/keys.js +43 -0
  63. package/dist/cjs/perps/pdas.d.ts +29 -0
  64. package/dist/cjs/perps/pdas.js +55 -0
  65. package/dist/cjs/perps/relayer.d.ts +9 -0
  66. package/dist/cjs/perps/relayer.js +35 -0
  67. package/dist/cjs/perps/types.d.ts +126 -0
  68. package/dist/cjs/perps/types.js +2 -0
  69. package/dist/cjs/positions/index.d.ts +4 -0
  70. package/dist/cjs/positions/index.js +20 -0
  71. package/dist/cjs/positions/keys.d.ts +29 -0
  72. package/dist/cjs/positions/keys.js +71 -0
  73. package/dist/cjs/positions/pdas.d.ts +15 -0
  74. package/dist/cjs/positions/pdas.js +54 -0
  75. package/dist/cjs/positions/relayer.d.ts +4 -0
  76. package/dist/cjs/positions/relayer.js +15 -0
  77. package/dist/cjs/positions/types.d.ts +97 -0
  78. package/dist/cjs/positions/types.js +2 -0
  79. package/dist/cjs/predictions/client.d.ts +41 -0
  80. package/dist/cjs/predictions/client.js +147 -0
  81. package/dist/cjs/predictions/index.d.ts +5 -0
  82. package/dist/cjs/predictions/index.js +21 -0
  83. package/dist/cjs/predictions/keys.d.ts +14 -0
  84. package/dist/cjs/predictions/keys.js +40 -0
  85. package/dist/cjs/predictions/pdas.d.ts +6 -0
  86. package/dist/cjs/predictions/pdas.js +13 -0
  87. package/dist/cjs/predictions/relayer.d.ts +3 -0
  88. package/dist/cjs/predictions/relayer.js +11 -0
  89. package/dist/cjs/predictions/types.d.ts +178 -0
  90. package/dist/cjs/predictions/types.js +2 -0
  91. package/dist/cjs/program.d.ts +2 -0
  92. package/dist/cjs/program.js +8 -7
  93. package/dist/cjs/prover.d.ts +27 -4
  94. package/dist/cjs/prover.js +107 -48
  95. package/dist/cjs/relayer/api.d.ts +41 -0
  96. package/dist/cjs/relayer/api.js +99 -0
  97. package/dist/cjs/relayer/client.d.ts +42 -17
  98. package/dist/cjs/relayer/client.js +94 -17
  99. package/dist/cjs/relayer/errors.d.ts +1 -1
  100. package/dist/cjs/relayer/errors.js +1 -1
  101. package/dist/cjs/relayer/index.d.ts +4 -1
  102. package/dist/cjs/relayer/index.js +1 -1
  103. package/dist/cjs/relayer/internal-config.d.ts +36 -0
  104. package/dist/cjs/relayer/internal-config.js +9 -0
  105. package/dist/cjs/relayer/internal.d.ts +6 -0
  106. package/dist/cjs/relayer/internal.js +14 -0
  107. package/dist/cjs/relayer/transport.d.ts +4 -2
  108. package/dist/cjs/relayer/transport.js +10 -5
  109. package/dist/cjs/relayer/types.d.ts +40 -10
  110. package/dist/cjs/relayer/types.js +1 -1
  111. package/dist/cjs/shield/owner.js +1 -4
  112. package/dist/esm/events/index.d.ts +6 -0
  113. package/dist/esm/events/index.js +6 -0
  114. package/dist/esm/events/parsing.d.ts +25 -0
  115. package/dist/esm/events/parsing.js +120 -0
  116. package/dist/esm/events/position.d.ts +26 -0
  117. package/dist/esm/events/position.js +48 -0
  118. package/dist/esm/events/recovery.d.ts +87 -0
  119. package/dist/esm/events/recovery.js +237 -0
  120. package/dist/esm/events/scanning.d.ts +35 -0
  121. package/dist/esm/events/scanning.js +92 -0
  122. package/dist/esm/events/tree.d.ts +27 -0
  123. package/dist/esm/events/tree.js +58 -0
  124. package/dist/esm/events/types.d.ts +39 -0
  125. package/dist/esm/events/types.js +1 -0
  126. package/dist/esm/events.d.ts +1 -77
  127. package/dist/esm/events.js +3 -129
  128. package/dist/esm/identity/encoding.d.ts +9 -0
  129. package/dist/esm/identity/encoding.js +75 -0
  130. package/dist/esm/identity/index.d.ts +4 -0
  131. package/dist/esm/identity/index.js +4 -0
  132. package/dist/esm/identity/noteKey.d.ts +33 -0
  133. package/dist/esm/identity/noteKey.js +91 -0
  134. package/dist/esm/identity/spending.d.ts +18 -0
  135. package/dist/esm/identity/spending.js +35 -0
  136. package/dist/esm/identity/viewKey.d.ts +38 -0
  137. package/dist/esm/identity/viewKey.js +96 -0
  138. package/dist/esm/idl/index.d.ts +18 -0
  139. package/dist/esm/idl/index.js +18 -0
  140. package/dist/esm/idl/privacy_pool.json +9907 -9907
  141. package/dist/esm/idl/privacy_pool_legacy.d.ts +5 -0
  142. package/dist/esm/idl/privacy_pool_legacy.js +3305 -0
  143. package/dist/esm/idl/privacy_pool_legacy.json +2302 -0
  144. package/dist/esm/idl/privacy_pool_legacy2.d.ts +5 -0
  145. package/dist/esm/idl/privacy_pool_legacy2.js +3395 -0
  146. package/dist/esm/idl/privacy_pool_legacy2.json +2376 -0
  147. package/dist/esm/index.d.ts +8 -3
  148. package/dist/esm/index.js +8 -3
  149. package/dist/esm/notes/amount.d.ts +2 -0
  150. package/dist/esm/notes/amount.js +18 -0
  151. package/dist/esm/notes/index.d.ts +4 -0
  152. package/dist/esm/notes/index.js +4 -0
  153. package/dist/esm/notes/recovery.d.ts +16 -6
  154. package/dist/esm/notes/recovery.js +33 -16
  155. package/dist/esm/notes/scan.d.ts +74 -0
  156. package/dist/esm/notes/scan.js +105 -0
  157. package/dist/esm/notes/selection.d.ts +133 -0
  158. package/dist/esm/notes/selection.js +254 -0
  159. package/dist/esm/notes/spent.d.ts +60 -0
  160. package/dist/esm/notes/spent.js +96 -0
  161. package/dist/esm/perps/constants.d.ts +16 -0
  162. package/dist/esm/perps/constants.js +48 -0
  163. package/dist/esm/perps/index.d.ts +5 -0
  164. package/dist/esm/perps/index.js +5 -0
  165. package/dist/esm/perps/keys.d.ts +16 -0
  166. package/dist/esm/perps/keys.js +35 -0
  167. package/dist/esm/perps/pdas.d.ts +29 -0
  168. package/dist/esm/perps/pdas.js +47 -0
  169. package/dist/esm/perps/relayer.d.ts +9 -0
  170. package/dist/esm/perps/relayer.js +25 -0
  171. package/dist/esm/perps/types.d.ts +126 -0
  172. package/dist/esm/perps/types.js +1 -0
  173. package/dist/esm/positions/index.d.ts +4 -0
  174. package/dist/esm/positions/index.js +4 -0
  175. package/dist/esm/positions/keys.d.ts +29 -0
  176. package/dist/esm/positions/keys.js +65 -0
  177. package/dist/esm/positions/pdas.d.ts +15 -0
  178. package/dist/esm/positions/pdas.js +44 -0
  179. package/dist/esm/positions/relayer.d.ts +4 -0
  180. package/dist/esm/positions/relayer.js +10 -0
  181. package/dist/esm/positions/types.d.ts +97 -0
  182. package/dist/esm/positions/types.js +1 -0
  183. package/dist/esm/predictions/client.d.ts +41 -0
  184. package/dist/esm/predictions/client.js +141 -0
  185. package/dist/esm/predictions/index.d.ts +5 -0
  186. package/dist/esm/predictions/index.js +5 -0
  187. package/dist/esm/predictions/keys.d.ts +14 -0
  188. package/dist/esm/predictions/keys.js +33 -0
  189. package/dist/esm/predictions/pdas.d.ts +6 -0
  190. package/dist/esm/predictions/pdas.js +10 -0
  191. package/dist/esm/predictions/relayer.d.ts +3 -0
  192. package/dist/esm/predictions/relayer.js +7 -0
  193. package/dist/esm/predictions/types.d.ts +178 -0
  194. package/dist/esm/predictions/types.js +1 -0
  195. package/dist/esm/program.d.ts +2 -0
  196. package/dist/esm/program.js +4 -3
  197. package/dist/esm/prover.d.ts +27 -4
  198. package/dist/esm/prover.js +106 -15
  199. package/dist/esm/relayer/api.d.ts +41 -0
  200. package/dist/esm/relayer/api.js +66 -0
  201. package/dist/esm/relayer/client.d.ts +42 -17
  202. package/dist/esm/relayer/client.js +94 -17
  203. package/dist/esm/relayer/errors.d.ts +1 -1
  204. package/dist/esm/relayer/errors.js +1 -1
  205. package/dist/esm/relayer/index.d.ts +4 -1
  206. package/dist/esm/relayer/index.js +1 -1
  207. package/dist/esm/relayer/internal-config.d.ts +36 -0
  208. package/dist/esm/relayer/internal-config.js +6 -0
  209. package/dist/esm/relayer/internal.d.ts +6 -0
  210. package/dist/esm/relayer/internal.js +10 -0
  211. package/dist/esm/relayer/transport.d.ts +4 -2
  212. package/dist/esm/relayer/transport.js +10 -5
  213. package/dist/esm/relayer/types.d.ts +40 -10
  214. package/dist/esm/relayer/types.js +1 -1
  215. package/dist/esm/shield/owner.js +1 -4
  216. package/identity.d.ts +2 -0
  217. package/identity.js +3 -0
  218. package/idl.d.ts +2 -0
  219. package/idl.js +3 -0
  220. package/notes.d.ts +2 -0
  221. package/notes.js +3 -0
  222. package/package.json +85 -3
  223. package/perps.d.ts +2 -0
  224. package/perps.js +3 -0
  225. package/poseidon.d.ts +2 -0
  226. package/poseidon.js +3 -0
  227. package/positions.d.ts +2 -0
  228. package/positions.js +3 -0
  229. package/predictions.d.ts +2 -0
  230. package/predictions.js +3 -0
  231. package/proof.d.ts +2 -0
  232. package/proof.js +3 -0
  233. package/prover.d.ts +2 -0
  234. package/prover.js +3 -0
  235. package/relayer.d.ts +2 -0
  236. package/relayer.js +3 -0
  237. package/shield.d.ts +2 -0
  238. package/shield.js +3 -0
  239. package/transactions.d.ts +2 -0
  240. package/transactions.js +3 -0
@@ -0,0 +1,39 @@
1
+ import type { PublicKey } from "@solana/web3.js";
2
+ import type { PrivacyPoolIdlVersion } from "../idl/index.js";
3
+ export type CommitmentEventSource = "emitted" | "computed" | "protected";
4
+ /**
5
+ * A commitment appended to a Veilo Merkle tree.
6
+ *
7
+ * Compact recovery fields are optional because they were added across two
8
+ * program upgrades. Historical events remain valid without them.
9
+ */
10
+ export type CommitmentEvent = {
11
+ commitment: Uint8Array;
12
+ leafIndex: number;
13
+ newRoot: Uint8Array;
14
+ timestamp: number;
15
+ mintAddress: PublicKey;
16
+ treeId: number;
17
+ txSignature: string;
18
+ slot: number;
19
+ ephemeralPublicKey?: Uint8Array;
20
+ encryptedBlob?: Uint8Array;
21
+ viewTag?: number;
22
+ source?: CommitmentEventSource;
23
+ idlVersion?: PrivacyPoolIdlVersion;
24
+ };
25
+ /** On-chain event emitted when a private note is consumed. */
26
+ export type NullifierSpentEvent = {
27
+ nullifier: Uint8Array;
28
+ timestamp: number;
29
+ mintAddress: PublicKey;
30
+ treeId: number;
31
+ txSignature: string;
32
+ slot: number;
33
+ idlVersion?: PrivacyPoolIdlVersion;
34
+ };
35
+ export type ParsedVeiloEvent = {
36
+ name: string;
37
+ data: unknown;
38
+ idlVersion: PrivacyPoolIdlVersion;
39
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,77 +1 @@
1
- import { PublicKey } from "@solana/web3.js";
2
- import { Program, Idl } from "@coral-xyz/anchor";
3
- import { MerkleTree } from "./merkle.js";
4
- /**
5
- * On-chain CommitmentEvent emitted by `transact` and `transact_swap`.
6
- * Mirrors the IDL CommitmentEvent struct.
7
- */
8
- export type CommitmentEvent = {
9
- commitment: Uint8Array;
10
- leafIndex: number;
11
- newRoot: Uint8Array;
12
- timestamp: number;
13
- mintAddress: PublicKey;
14
- treeId: number;
15
- txSignature: string;
16
- slot: number;
17
- };
18
- /**
19
- * On-chain NullifierSpent event emitted when a UTXO is consumed.
20
- * Mirrors the IDL NullifierSpent struct.
21
- */
22
- export type NullifierSpentEvent = {
23
- nullifier: Uint8Array;
24
- timestamp: number;
25
- mintAddress: PublicKey;
26
- treeId: number;
27
- txSignature: string;
28
- slot: number;
29
- };
30
- /**
31
- * Fetch and parse CommitmentEvents for a program, optionally filtered by mint.
32
- *
33
- * @param program - Anchor program instance
34
- * @param mintAddress - Filter to a specific pool; omit to get all pools
35
- * @param before - Start paging before this signature (exclusive)
36
- * @param until - Stop paging at this signature (exclusive)
37
- * @param limit - Max signatures to fetch per page (default 1000)
38
- */
39
- export declare function scanCommitmentEvents<T extends Idl>(params: {
40
- program: Program<T>;
41
- mintAddress?: PublicKey;
42
- before?: string;
43
- until?: string;
44
- limit?: number;
45
- }): Promise<CommitmentEvent[]>;
46
- /**
47
- * Fetch and parse NullifierSpent events for a program, optionally filtered by mint.
48
- */
49
- export declare function scanNullifierEvents<T extends Idl>(params: {
50
- program: Program<T>;
51
- mintAddress?: PublicKey;
52
- before?: string;
53
- until?: string;
54
- limit?: number;
55
- }): Promise<NullifierSpentEvent[]>;
56
- /**
57
- * Rebuild a local MerkleTree from on-chain CommitmentEvents.
58
- * Use this to get a valid inclusion proof for spending any UTXO.
59
- *
60
- * CommitmentEvents are sorted by (treeId, leafIndex) so the local tree
61
- * matches the on-chain state exactly.
62
- *
63
- * @param program - Anchor program instance
64
- * @param mintAddress - Pool to reconstruct
65
- * @param treeId - Which tree to reconstruct (default 0)
66
- * @param depth - Merkle tree depth (default 22, must match on-chain)
67
- */
68
- export declare function buildTreeFromEvents<T extends Idl>(params: {
69
- program: Program<T>;
70
- mintAddress: PublicKey;
71
- treeId?: number;
72
- depth?: number;
73
- }): Promise<{
74
- tree: MerkleTree;
75
- events: CommitmentEvent[];
76
- latestSignature?: string;
77
- }>;
1
+ export * from "./events/index.js";
@@ -10,158 +10,10 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
10
10
  if (k2 === undefined) k2 = k;
11
11
  o[k2] = m[k];
12
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
- })();
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
35
16
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.scanCommitmentEvents = scanCommitmentEvents;
37
- exports.scanNullifierEvents = scanNullifierEvents;
38
- exports.buildTreeFromEvents = buildTreeFromEvents;
39
- const anchor = __importStar(require("@coral-xyz/anchor"));
40
- const merkle_js_1 = require("./merkle.js");
41
- // -----------------------------------------------------------------------------
42
- // Event Scanning
43
- // -----------------------------------------------------------------------------
44
- /**
45
- * Fetch and parse CommitmentEvents for a program, optionally filtered by mint.
46
- *
47
- * @param program - Anchor program instance
48
- * @param mintAddress - Filter to a specific pool; omit to get all pools
49
- * @param before - Start paging before this signature (exclusive)
50
- * @param until - Stop paging at this signature (exclusive)
51
- * @param limit - Max signatures to fetch per page (default 1000)
52
- */
53
- async function scanCommitmentEvents(params) {
54
- const { program, mintAddress, before, until, limit = 1000 } = params;
55
- const out = [];
56
- const eventParser = new anchor.EventParser(program.programId, new anchor.BorshCoder(program.idl));
57
- const sigs = await program.provider.connection.getSignaturesForAddress(program.programId, { before, until, limit });
58
- for (const sigInfo of sigs) {
59
- if (sigInfo.err)
60
- continue;
61
- const tx = await program.provider.connection.getTransaction(sigInfo.signature, { commitment: "confirmed", maxSupportedTransactionVersion: 0 });
62
- if (!tx)
63
- continue;
64
- const events = Array.from(eventParser.parseLogs(tx.meta?.logMessages ?? []));
65
- for (const ev of events) {
66
- if (ev.name !== "commitmentEvent")
67
- continue;
68
- const d = ev.data;
69
- const evMint = d.mintAddress;
70
- if (mintAddress && !evMint.equals(mintAddress))
71
- continue;
72
- out.push({
73
- commitment: new Uint8Array(d.commitment),
74
- leafIndex: Number(d.leafIndex),
75
- newRoot: new Uint8Array(d.newRoot),
76
- timestamp: Number(d.timestamp),
77
- mintAddress: evMint,
78
- treeId: Number(d.treeId),
79
- txSignature: sigInfo.signature,
80
- slot: sigInfo.slot,
81
- });
82
- }
83
- }
84
- return out;
85
- }
86
- /**
87
- * Fetch and parse NullifierSpent events for a program, optionally filtered by mint.
88
- */
89
- async function scanNullifierEvents(params) {
90
- const { program, mintAddress, before, until, limit = 1000 } = params;
91
- const out = [];
92
- const eventParser = new anchor.EventParser(program.programId, new anchor.BorshCoder(program.idl));
93
- const sigs = await program.provider.connection.getSignaturesForAddress(program.programId, { before, until, limit });
94
- for (const sigInfo of sigs) {
95
- if (sigInfo.err)
96
- continue;
97
- const tx = await program.provider.connection.getTransaction(sigInfo.signature, { commitment: "confirmed", maxSupportedTransactionVersion: 0 });
98
- if (!tx)
99
- continue;
100
- const events = Array.from(eventParser.parseLogs(tx.meta?.logMessages ?? []));
101
- for (const ev of events) {
102
- if (ev.name !== "nullifierSpent")
103
- continue;
104
- const d = ev.data;
105
- const evMint = d.mintAddress;
106
- if (mintAddress && !evMint.equals(mintAddress))
107
- continue;
108
- out.push({
109
- nullifier: new Uint8Array(d.nullifier),
110
- timestamp: Number(d.timestamp),
111
- mintAddress: evMint,
112
- treeId: Number(d.treeId),
113
- txSignature: sigInfo.signature,
114
- slot: sigInfo.slot,
115
- });
116
- }
117
- }
118
- return out;
119
- }
120
- // -----------------------------------------------------------------------------
121
- // Tree Reconstruction
122
- // -----------------------------------------------------------------------------
123
- /**
124
- * Rebuild a local MerkleTree from on-chain CommitmentEvents.
125
- * Use this to get a valid inclusion proof for spending any UTXO.
126
- *
127
- * CommitmentEvents are sorted by (treeId, leafIndex) so the local tree
128
- * matches the on-chain state exactly.
129
- *
130
- * @param program - Anchor program instance
131
- * @param mintAddress - Pool to reconstruct
132
- * @param treeId - Which tree to reconstruct (default 0)
133
- * @param depth - Merkle tree depth (default 22, must match on-chain)
134
- */
135
- async function buildTreeFromEvents(params) {
136
- const { program, mintAddress, treeId = 0, depth = 22 } = params;
137
- // Fetch all commitment events for this pool (page until no more results).
138
- // Oldest-first so we insert leaves in the correct order.
139
- const allEvents = [];
140
- let before;
141
- while (true) {
142
- const page = await scanCommitmentEvents({
143
- program,
144
- mintAddress,
145
- before,
146
- limit: 1000,
147
- });
148
- if (page.length === 0)
149
- break;
150
- allEvents.push(...page);
151
- before = page[page.length - 1].txSignature;
152
- if (page.length < 1000)
153
- break;
154
- }
155
- // Keep only events for this treeId, sort by leafIndex ascending
156
- const treeEvents = allEvents
157
- .filter((e) => e.treeId === treeId)
158
- .sort((a, b) => a.leafIndex - b.leafIndex);
159
- const tree = new merkle_js_1.MerkleTree(depth);
160
- for (const ev of treeEvents) {
161
- tree.insert(ev.commitment);
162
- }
163
- const latestSignature = treeEvents.length > 0
164
- ? treeEvents[treeEvents.length - 1].txSignature
165
- : undefined;
166
- return { tree, events: treeEvents, latestSignature };
167
- }
17
+ // Backward-compatible entry point. Event parsing, scanning, and recovery live
18
+ // in focused modules under src/events.
19
+ __exportStar(require("./events/index.js"), exports);
@@ -0,0 +1,9 @@
1
+ export declare function concatBytes(...parts: readonly Uint8Array[]): Uint8Array;
2
+ export declare function utf8(value: string): Uint8Array;
3
+ export declare function uint32Le(value: number, label?: string): Uint8Array;
4
+ export declare function uint64Le(value: bigint, label?: string): Uint8Array;
5
+ export declare function assertBytes(value: Uint8Array, length: number, label: string): void;
6
+ export declare function bytesToHex(bytes: Uint8Array): string;
7
+ export declare function hexToBytes(value: string, length?: number, label?: string): Uint8Array;
8
+ /** Encode bytes using the Bitcoin/Solana base58 alphabet. */
9
+ export declare function encodeBase58(bytes: Uint8Array): string;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.concatBytes = concatBytes;
4
+ exports.utf8 = utf8;
5
+ exports.uint32Le = uint32Le;
6
+ exports.uint64Le = uint64Le;
7
+ exports.assertBytes = assertBytes;
8
+ exports.bytesToHex = bytesToHex;
9
+ exports.hexToBytes = hexToBytes;
10
+ exports.encodeBase58 = encodeBase58;
11
+ const BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
12
+ function concatBytes(...parts) {
13
+ const output = new Uint8Array(parts.reduce((length, part) => length + part.length, 0));
14
+ let offset = 0;
15
+ for (const part of parts) {
16
+ output.set(part, offset);
17
+ offset += part.length;
18
+ }
19
+ return output;
20
+ }
21
+ function utf8(value) {
22
+ return new TextEncoder().encode(value);
23
+ }
24
+ function uint32Le(value, label = "value") {
25
+ if (!Number.isSafeInteger(value) || value < 0 || value > 4294967295) {
26
+ throw new RangeError(`${label} must be an unsigned 32-bit integer`);
27
+ }
28
+ const bytes = new Uint8Array(4);
29
+ new DataView(bytes.buffer).setUint32(0, value, true);
30
+ return bytes;
31
+ }
32
+ function uint64Le(value, label = "value") {
33
+ if (value < 0n || value > 0xffffffffffffffffn) {
34
+ throw new RangeError(`${label} must be an unsigned 64-bit integer`);
35
+ }
36
+ const bytes = new Uint8Array(8);
37
+ new DataView(bytes.buffer).setBigUint64(0, value, true);
38
+ return bytes;
39
+ }
40
+ function assertBytes(value, length, label) {
41
+ if (value.length !== length) {
42
+ throw new RangeError(`${label} must be ${length} bytes, got ${value.length}`);
43
+ }
44
+ }
45
+ function bytesToHex(bytes) {
46
+ return Array.from(bytes, (value) => value.toString(16).padStart(2, "0")).join("");
47
+ }
48
+ function hexToBytes(value, length, label = "hex value") {
49
+ const clean = value.startsWith("0x") ? value.slice(2) : value;
50
+ if (!/^[0-9a-f]*$/i.test(clean) || clean.length % 2 !== 0) {
51
+ throw new TypeError(`${label} must be an even-length hexadecimal string`);
52
+ }
53
+ const bytes = Uint8Array.from({ length: clean.length / 2 }, (_, index) => Number.parseInt(clean.slice(index * 2, index * 2 + 2), 16));
54
+ if (length !== undefined)
55
+ assertBytes(bytes, length, label);
56
+ return bytes;
57
+ }
58
+ /** Encode bytes using the Bitcoin/Solana base58 alphabet. */
59
+ function encodeBase58(bytes) {
60
+ if (bytes.length === 0)
61
+ return "";
62
+ let zeroes = 0;
63
+ while (zeroes < bytes.length && bytes[zeroes] === 0)
64
+ zeroes++;
65
+ if (zeroes === bytes.length)
66
+ return "1".repeat(zeroes);
67
+ const digits = [0];
68
+ for (let index = zeroes; index < bytes.length; index++) {
69
+ let carry = bytes[index];
70
+ for (let digit = 0; digit < digits.length; digit++) {
71
+ const value = digits[digit] * 256 + carry;
72
+ digits[digit] = value % 58;
73
+ carry = Math.floor(value / 58);
74
+ }
75
+ while (carry > 0) {
76
+ digits.push(carry % 58);
77
+ carry = Math.floor(carry / 58);
78
+ }
79
+ }
80
+ let encoded = "1".repeat(zeroes);
81
+ for (let index = digits.length - 1; index >= 0; index--) {
82
+ encoded += BASE58_ALPHABET[digits[index]];
83
+ }
84
+ return encoded;
85
+ }
@@ -0,0 +1,4 @@
1
+ export * from "./encoding.js";
2
+ export * from "./spending.js";
3
+ export * from "./noteKey.js";
4
+ export * from "./viewKey.js";
@@ -0,0 +1,20 @@
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./encoding.js"), exports);
18
+ __exportStar(require("./spending.js"), exports);
19
+ __exportStar(require("./noteKey.js"), exports);
20
+ __exportStar(require("./viewKey.js"), exports);
@@ -0,0 +1,33 @@
1
+ /** Domain-separation label. Permanent — see the header. */
2
+ export declare const VEILO_NOTE_KEY_LABEL = "veilo_note_key_v1";
3
+ /** The note spending key plus the Poseidon public key derived from it. */
4
+ export interface NoteKeypair {
5
+ /** Raw 32-byte scalar, strictly below the BN254 Fr modulus. */
6
+ noteSecretKey: Uint8Array;
7
+ /** Hex form, matching how the relayer has always returned this key. */
8
+ noteSecretKeyHex: string;
9
+ /** Poseidon(noteSecretKey) — the note's committed owner. */
10
+ notePublicKey: bigint;
11
+ /** Decimal string form, as the relayer and note scanner expect it. */
12
+ notePublicKeyString: string;
13
+ }
14
+ /**
15
+ * Derive the note spending key from a spending-key root.
16
+ *
17
+ * @param spendingKey 32 bytes from `deriveSpendingKeyFromSignature` or a sibling
18
+ */
19
+ export declare function deriveNoteKeyFromSpendingKey(spendingKey: Uint8Array): Uint8Array;
20
+ /**
21
+ * Derive the note spending key and its Poseidon public key.
22
+ *
23
+ * Call `initPoseidon()` once before this, as with `derivePositionKeys`.
24
+ */
25
+ export declare function deriveNoteKeypairFromSpendingKey(spendingKey: Uint8Array): NoteKeypair;
26
+ /**
27
+ * One-shot derivation for a dapp holding only a wallet-standard `signMessage`.
28
+ *
29
+ * Prompts a single signature, then returns spend authority for the account.
30
+ * The signature is secret material: keep it in memory, never persist it, and
31
+ * never expose the result on a global.
32
+ */
33
+ export declare function deriveNoteKeypairWithSigner(signMessage: (message: Uint8Array) => Promise<Uint8Array>, index?: number): Promise<NoteKeypair>;
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VEILO_NOTE_KEY_LABEL = void 0;
4
+ exports.deriveNoteKeyFromSpendingKey = deriveNoteKeyFromSpendingKey;
5
+ exports.deriveNoteKeypairFromSpendingKey = deriveNoteKeypairFromSpendingKey;
6
+ exports.deriveNoteKeypairWithSigner = deriveNoteKeypairWithSigner;
7
+ /**
8
+ * Derivation of the Veilo NOTE SPENDING KEY from a spending-key root.
9
+ *
10
+ * ⚠ BYTE-FOR-BYTE PORT — must agree with
11
+ * veilo-browser-extension/extension-ui/src/lib/veiloNoteKey.ts
12
+ * wallet-app/src/lib/veiloNoteKey.ts
13
+ * An account created in one client must be spendable from the others, so the
14
+ * label, the HMAC construction and the rejection rule are all load-bearing.
15
+ * `tests/identity-keys.test.ts` re-implements the client algorithm
16
+ * independently and asserts equality, plus pins a known-answer vector.
17
+ *
18
+ * WHAT THIS KEY IS
19
+ * ----------------
20
+ * `zk-circuits/keypair.circom` defines publicKey = Poseidon(privateKey), and
21
+ * `transaction.circom` constrains Poseidon(privateKey) === the note's committed
22
+ * owner before it will emit a proof, then derives the nullifier from the same
23
+ * key. This one scalar is both proof of ownership and spend authority; there is
24
+ * no second factor anywhere in the circuit. Treat it exactly as you would a
25
+ * wallet secret key.
26
+ *
27
+ * Derivation:
28
+ * spendingKey = deriveSpendingKeyFromSignature(sig) // ./spending.js
29
+ * veiloPrivateKey = rejectionSample(hmac_sha256(spendingKey, "veilo_note_key_v1|N"))
30
+ * veiloPublicKey = Poseidon(veiloPrivateKey)
31
+ *
32
+ * WHY REJECTION SAMPLING AND NOT `mod Fr`
33
+ * ---------------------------------------
34
+ * Reducing a 256-bit hash modulo Fr biases the low end of the range. Note that
35
+ * `derivePositionKeys` uses modular reduction; this key follows the stricter
36
+ * convention because it is a SPENDING key, matching how real note secrets are
37
+ * generated. About 0.3% of draws are retried.
38
+ *
39
+ * ⚠ THE LABEL IS PERMANENT. Once one note exists under "veilo_note_key_v1",
40
+ * changing the label or the sampling method makes that note unspendable
41
+ * forever. Version it, never edit it.
42
+ *
43
+ * ⚠ APPLIES TO `derived-v3` ACCOUNTS ONLY. Accounts whose relayer record has
44
+ * `veiloKeySource` absent or "legacy" have a SERVER-GENERATED note key that no
45
+ * derivation can reproduce — those clients must decrypt the key the relayer
46
+ * serves them. Check the account's key source before assuming this function
47
+ * yields a usable key.
48
+ */
49
+ const hmac_1 = require("@noble/hashes/hmac");
50
+ const sha256_1 = require("@noble/hashes/sha256");
51
+ const poseidon_js_1 = require("../poseidon.js");
52
+ const encoding_js_1 = require("./encoding.js");
53
+ const spending_js_1 = require("./spending.js");
54
+ /** Domain-separation label. Permanent — see the header. */
55
+ exports.VEILO_NOTE_KEY_LABEL = "veilo_note_key_v1";
56
+ /** Practically unreachable: 256 consecutive rejections is ~1e-640. */
57
+ const MAX_REJECTION_ROUNDS = 256;
58
+ /**
59
+ * Derive the note spending key from a spending-key root.
60
+ *
61
+ * @param spendingKey 32 bytes from `deriveSpendingKeyFromSignature` or a sibling
62
+ */
63
+ function deriveNoteKeyFromSpendingKey(spendingKey) {
64
+ (0, encoding_js_1.assertBytes)(spendingKey, 32, "spending key");
65
+ for (let counter = 0; counter < MAX_REJECTION_ROUNDS; counter++) {
66
+ const candidate = (0, hmac_1.hmac)(sha256_1.sha256, spendingKey, (0, encoding_js_1.utf8)(`${exports.VEILO_NOTE_KEY_LABEL}|${counter}`));
67
+ if ((0, poseidon_js_1.bytesToBigIntBE)(candidate) < poseidon_js_1.BN254_FR_MODULUS)
68
+ return candidate;
69
+ }
70
+ // Reaching here means HMAC-SHA256 is broken, not that we were unlucky.
71
+ throw new Error(`Failed to derive a field element for "${exports.VEILO_NOTE_KEY_LABEL}"`);
72
+ }
73
+ /**
74
+ * Derive the note spending key and its Poseidon public key.
75
+ *
76
+ * Call `initPoseidon()` once before this, as with `derivePositionKeys`.
77
+ */
78
+ function deriveNoteKeypairFromSpendingKey(spendingKey) {
79
+ const noteSecretKey = deriveNoteKeyFromSpendingKey(spendingKey);
80
+ const notePublicKey = (0, poseidon_js_1.poseidon1)((0, poseidon_js_1.bytesToBigIntBE)(noteSecretKey));
81
+ return {
82
+ noteSecretKey,
83
+ noteSecretKeyHex: (0, encoding_js_1.bytesToHex)(noteSecretKey),
84
+ notePublicKey,
85
+ notePublicKeyString: notePublicKey.toString(),
86
+ };
87
+ }
88
+ /**
89
+ * One-shot derivation for a dapp holding only a wallet-standard `signMessage`.
90
+ *
91
+ * Prompts a single signature, then returns spend authority for the account.
92
+ * The signature is secret material: keep it in memory, never persist it, and
93
+ * never expose the result on a global.
94
+ */
95
+ async function deriveNoteKeypairWithSigner(signMessage, index = 0) {
96
+ return deriveNoteKeypairFromSpendingKey(await (0, spending_js_1.deriveSpendingKeyWithSigner)(signMessage, index));
97
+ }
@@ -0,0 +1,18 @@
1
+ import { Keypair } from "@solana/web3.js";
2
+ export declare const VEILO_SPENDING_KEY_DOMAIN = "veilo_spending_key_v1";
3
+ /** Exact message signed by Veilo clients to derive a spending-key root. */
4
+ export declare function getSpendingKeyMessage(index?: number): Uint8Array;
5
+ /** Convert the deterministic 64-byte wallet signature into a spending key. */
6
+ export declare function deriveSpendingKeyFromSignature(signature: Uint8Array): Uint8Array;
7
+ /**
8
+ * Wallet-standard-friendly spending-key derivation.
9
+ * The callback owns signing; the SDK never receives the wallet secret key.
10
+ */
11
+ export declare function deriveSpendingKeyWithSigner(signMessage: (message: Uint8Array) => Promise<Uint8Array>, index?: number): Promise<Uint8Array>;
12
+ /**
13
+ * Keypair convenience matching the wallet-app and extension implementation.
14
+ * Keep the keypair on the user's device and never send it to a service.
15
+ */
16
+ export declare function deriveSpendingKeyFromKeypair(keypair: Keypair, index?: number): Uint8Array;
17
+ /** Serialize an ephemeral claimant secret for an encrypted relayer request. */
18
+ export declare function encodeClaimantSecretKey(keypairOrSecret: Keypair | Uint8Array): string;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.VEILO_SPENDING_KEY_DOMAIN = void 0;
7
+ exports.getSpendingKeyMessage = getSpendingKeyMessage;
8
+ exports.deriveSpendingKeyFromSignature = deriveSpendingKeyFromSignature;
9
+ exports.deriveSpendingKeyWithSigner = deriveSpendingKeyWithSigner;
10
+ exports.deriveSpendingKeyFromKeypair = deriveSpendingKeyFromKeypair;
11
+ exports.encodeClaimantSecretKey = encodeClaimantSecretKey;
12
+ const sha256_1 = require("@noble/hashes/sha256");
13
+ const tweetnacl_1 = __importDefault(require("tweetnacl"));
14
+ const encoding_js_1 = require("./encoding.js");
15
+ exports.VEILO_SPENDING_KEY_DOMAIN = "veilo_spending_key_v1";
16
+ /** Exact message signed by Veilo clients to derive a spending-key root. */
17
+ function getSpendingKeyMessage(index = 0) {
18
+ return (0, encoding_js_1.concatBytes)((0, encoding_js_1.utf8)(exports.VEILO_SPENDING_KEY_DOMAIN), (0, encoding_js_1.uint32Le)(index, "spending-key index"));
19
+ }
20
+ /** Convert the deterministic 64-byte wallet signature into a spending key. */
21
+ function deriveSpendingKeyFromSignature(signature) {
22
+ (0, encoding_js_1.assertBytes)(signature, 64, "spending-key signature");
23
+ return (0, sha256_1.sha256)(signature);
24
+ }
25
+ /**
26
+ * Wallet-standard-friendly spending-key derivation.
27
+ * The callback owns signing; the SDK never receives the wallet secret key.
28
+ */
29
+ async function deriveSpendingKeyWithSigner(signMessage, index = 0) {
30
+ return deriveSpendingKeyFromSignature(await signMessage(getSpendingKeyMessage(index)));
31
+ }
32
+ /**
33
+ * Keypair convenience matching the wallet-app and extension implementation.
34
+ * Keep the keypair on the user's device and never send it to a service.
35
+ */
36
+ function deriveSpendingKeyFromKeypair(keypair, index = 0) {
37
+ return deriveSpendingKeyFromSignature(tweetnacl_1.default.sign.detached(getSpendingKeyMessage(index), keypair.secretKey));
38
+ }
39
+ /** Serialize an ephemeral claimant secret for an encrypted relayer request. */
40
+ function encodeClaimantSecretKey(keypairOrSecret) {
41
+ const secret = keypairOrSecret instanceof Uint8Array
42
+ ? keypairOrSecret
43
+ : keypairOrSecret.secretKey;
44
+ (0, encoding_js_1.assertBytes)(secret, 64, "claimant secret key");
45
+ return (0, encoding_js_1.encodeBase58)(secret);
46
+ }
@@ -0,0 +1,38 @@
1
+ import type { CompactNoteCipher } from "../compactNote.js";
2
+ /** HKDF salt. Provisional — see the header. */
3
+ export declare const VEILO_VIEW_KEY_SALT = "veilo_view_v1";
4
+ /** HKDF info. Provisional — see the header. */
5
+ export declare const VEILO_VIEW_KEY_INFO = "x25519";
6
+ /** An X25519 keypair used only to decrypt notes. */
7
+ export interface ViewKeypair {
8
+ /** 32-byte clamped X25519 scalar. Secret: decrypts every note sent to it. */
9
+ viewSecretKey: Uint8Array;
10
+ /** 32-byte X25519 public key — the value senders encrypt to. */
11
+ viewPublicKey: Uint8Array;
12
+ }
13
+ /** Derive the view keypair from a spending-key root. */
14
+ export declare function deriveViewKeypairFromSpendingKey(spendingKey: Uint8Array): ViewKeypair;
15
+ /**
16
+ * One-shot derivation for a dapp holding only a wallet-standard `signMessage`.
17
+ *
18
+ * Uses the same signature as `deriveNoteKeypairWithSigner`, so a client that
19
+ * wants both prompts once and derives the spending key itself rather than
20
+ * calling both helpers.
21
+ */
22
+ export declare function deriveViewKeypairWithSigner(signMessage: (message: Uint8Array) => Promise<Uint8Array>, index?: number): Promise<ViewKeypair>;
23
+ /**
24
+ * Scan one candidate cipher with a view key.
25
+ *
26
+ * Returns `null` both for a view-tag miss and for a blob that was not encrypted
27
+ * to this key — the expected outcome for nearly every candidate. The shared
28
+ * secret is computed once and reused for the tag check and the open, which is
29
+ * the cheapest correct order for a scan loop: the tag rejects ~255/256
30
+ * candidates for one scalar multiplication and one hash.
31
+ *
32
+ * ⚠ Only decrypts notes encrypted TO `viewPublicKey`. Notes sealed to a wallet
33
+ * Ed25519 key — every note written before the v2 format — will not open here.
34
+ */
35
+ export declare function openCompactNoteWithViewKey(viewSecretKey: Uint8Array, cipher: CompactNoteCipher): {
36
+ blinding: Uint8Array;
37
+ amount: bigint;
38
+ } | null;