@veilo/sdk-core 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. package/README.md +237 -19
  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 +3 -0
  48. package/dist/cjs/notes/index.js +3 -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/selection.d.ts +77 -0
  52. package/dist/cjs/notes/selection.js +193 -0
  53. package/dist/cjs/notes/spent.d.ts +60 -0
  54. package/dist/cjs/notes/spent.js +101 -0
  55. package/dist/cjs/perps/constants.d.ts +16 -0
  56. package/dist/cjs/perps/constants.js +52 -0
  57. package/dist/cjs/perps/index.d.ts +5 -0
  58. package/dist/cjs/perps/index.js +21 -0
  59. package/dist/cjs/perps/keys.d.ts +16 -0
  60. package/dist/cjs/perps/keys.js +43 -0
  61. package/dist/cjs/perps/pdas.d.ts +29 -0
  62. package/dist/cjs/perps/pdas.js +55 -0
  63. package/dist/cjs/perps/relayer.d.ts +9 -0
  64. package/dist/cjs/perps/relayer.js +35 -0
  65. package/dist/cjs/perps/types.d.ts +126 -0
  66. package/dist/cjs/perps/types.js +2 -0
  67. package/dist/cjs/positions/index.d.ts +4 -0
  68. package/dist/cjs/positions/index.js +20 -0
  69. package/dist/cjs/positions/keys.d.ts +29 -0
  70. package/dist/cjs/positions/keys.js +71 -0
  71. package/dist/cjs/positions/pdas.d.ts +15 -0
  72. package/dist/cjs/positions/pdas.js +54 -0
  73. package/dist/cjs/positions/relayer.d.ts +4 -0
  74. package/dist/cjs/positions/relayer.js +15 -0
  75. package/dist/cjs/positions/types.d.ts +97 -0
  76. package/dist/cjs/positions/types.js +2 -0
  77. package/dist/cjs/predictions/client.d.ts +41 -0
  78. package/dist/cjs/predictions/client.js +147 -0
  79. package/dist/cjs/predictions/index.d.ts +5 -0
  80. package/dist/cjs/predictions/index.js +21 -0
  81. package/dist/cjs/predictions/keys.d.ts +14 -0
  82. package/dist/cjs/predictions/keys.js +40 -0
  83. package/dist/cjs/predictions/pdas.d.ts +6 -0
  84. package/dist/cjs/predictions/pdas.js +13 -0
  85. package/dist/cjs/predictions/relayer.d.ts +3 -0
  86. package/dist/cjs/predictions/relayer.js +11 -0
  87. package/dist/cjs/predictions/types.d.ts +178 -0
  88. package/dist/cjs/predictions/types.js +2 -0
  89. package/dist/cjs/program.d.ts +2 -0
  90. package/dist/cjs/program.js +8 -7
  91. package/dist/cjs/prover.d.ts +27 -4
  92. package/dist/cjs/prover.js +107 -48
  93. package/dist/cjs/relayer/api.d.ts +31 -0
  94. package/dist/cjs/relayer/api.js +86 -0
  95. package/dist/cjs/relayer/client.d.ts +29 -17
  96. package/dist/cjs/relayer/client.js +72 -17
  97. package/dist/cjs/relayer/errors.d.ts +1 -1
  98. package/dist/cjs/relayer/errors.js +1 -1
  99. package/dist/cjs/relayer/index.d.ts +4 -1
  100. package/dist/cjs/relayer/index.js +1 -1
  101. package/dist/cjs/relayer/internal-config.d.ts +36 -0
  102. package/dist/cjs/relayer/internal-config.js +9 -0
  103. package/dist/cjs/relayer/internal.d.ts +6 -0
  104. package/dist/cjs/relayer/internal.js +14 -0
  105. package/dist/cjs/relayer/transport.d.ts +4 -2
  106. package/dist/cjs/relayer/transport.js +10 -5
  107. package/dist/cjs/relayer/types.d.ts +9 -10
  108. package/dist/cjs/relayer/types.js +1 -1
  109. package/dist/cjs/shield/owner.js +1 -4
  110. package/dist/esm/events/index.d.ts +6 -0
  111. package/dist/esm/events/index.js +6 -0
  112. package/dist/esm/events/parsing.d.ts +25 -0
  113. package/dist/esm/events/parsing.js +120 -0
  114. package/dist/esm/events/position.d.ts +26 -0
  115. package/dist/esm/events/position.js +48 -0
  116. package/dist/esm/events/recovery.d.ts +87 -0
  117. package/dist/esm/events/recovery.js +237 -0
  118. package/dist/esm/events/scanning.d.ts +35 -0
  119. package/dist/esm/events/scanning.js +92 -0
  120. package/dist/esm/events/tree.d.ts +27 -0
  121. package/dist/esm/events/tree.js +58 -0
  122. package/dist/esm/events/types.d.ts +39 -0
  123. package/dist/esm/events/types.js +1 -0
  124. package/dist/esm/events.d.ts +1 -77
  125. package/dist/esm/events.js +3 -129
  126. package/dist/esm/identity/encoding.d.ts +9 -0
  127. package/dist/esm/identity/encoding.js +75 -0
  128. package/dist/esm/identity/index.d.ts +4 -0
  129. package/dist/esm/identity/index.js +4 -0
  130. package/dist/esm/identity/noteKey.d.ts +33 -0
  131. package/dist/esm/identity/noteKey.js +91 -0
  132. package/dist/esm/identity/spending.d.ts +18 -0
  133. package/dist/esm/identity/spending.js +35 -0
  134. package/dist/esm/identity/viewKey.d.ts +38 -0
  135. package/dist/esm/identity/viewKey.js +96 -0
  136. package/dist/esm/idl/index.d.ts +18 -0
  137. package/dist/esm/idl/index.js +18 -0
  138. package/dist/esm/idl/privacy_pool.json +9907 -9907
  139. package/dist/esm/idl/privacy_pool_legacy.d.ts +5 -0
  140. package/dist/esm/idl/privacy_pool_legacy.js +3305 -0
  141. package/dist/esm/idl/privacy_pool_legacy.json +2302 -0
  142. package/dist/esm/idl/privacy_pool_legacy2.d.ts +5 -0
  143. package/dist/esm/idl/privacy_pool_legacy2.js +3395 -0
  144. package/dist/esm/idl/privacy_pool_legacy2.json +2376 -0
  145. package/dist/esm/index.d.ts +8 -3
  146. package/dist/esm/index.js +8 -3
  147. package/dist/esm/notes/amount.d.ts +2 -0
  148. package/dist/esm/notes/amount.js +18 -0
  149. package/dist/esm/notes/index.d.ts +3 -0
  150. package/dist/esm/notes/index.js +3 -0
  151. package/dist/esm/notes/recovery.d.ts +16 -6
  152. package/dist/esm/notes/recovery.js +33 -16
  153. package/dist/esm/notes/selection.d.ts +77 -0
  154. package/dist/esm/notes/selection.js +188 -0
  155. package/dist/esm/notes/spent.d.ts +60 -0
  156. package/dist/esm/notes/spent.js +96 -0
  157. package/dist/esm/perps/constants.d.ts +16 -0
  158. package/dist/esm/perps/constants.js +48 -0
  159. package/dist/esm/perps/index.d.ts +5 -0
  160. package/dist/esm/perps/index.js +5 -0
  161. package/dist/esm/perps/keys.d.ts +16 -0
  162. package/dist/esm/perps/keys.js +35 -0
  163. package/dist/esm/perps/pdas.d.ts +29 -0
  164. package/dist/esm/perps/pdas.js +47 -0
  165. package/dist/esm/perps/relayer.d.ts +9 -0
  166. package/dist/esm/perps/relayer.js +25 -0
  167. package/dist/esm/perps/types.d.ts +126 -0
  168. package/dist/esm/perps/types.js +1 -0
  169. package/dist/esm/positions/index.d.ts +4 -0
  170. package/dist/esm/positions/index.js +4 -0
  171. package/dist/esm/positions/keys.d.ts +29 -0
  172. package/dist/esm/positions/keys.js +65 -0
  173. package/dist/esm/positions/pdas.d.ts +15 -0
  174. package/dist/esm/positions/pdas.js +44 -0
  175. package/dist/esm/positions/relayer.d.ts +4 -0
  176. package/dist/esm/positions/relayer.js +10 -0
  177. package/dist/esm/positions/types.d.ts +97 -0
  178. package/dist/esm/positions/types.js +1 -0
  179. package/dist/esm/predictions/client.d.ts +41 -0
  180. package/dist/esm/predictions/client.js +141 -0
  181. package/dist/esm/predictions/index.d.ts +5 -0
  182. package/dist/esm/predictions/index.js +5 -0
  183. package/dist/esm/predictions/keys.d.ts +14 -0
  184. package/dist/esm/predictions/keys.js +33 -0
  185. package/dist/esm/predictions/pdas.d.ts +6 -0
  186. package/dist/esm/predictions/pdas.js +10 -0
  187. package/dist/esm/predictions/relayer.d.ts +3 -0
  188. package/dist/esm/predictions/relayer.js +7 -0
  189. package/dist/esm/predictions/types.d.ts +178 -0
  190. package/dist/esm/predictions/types.js +1 -0
  191. package/dist/esm/program.d.ts +2 -0
  192. package/dist/esm/program.js +4 -3
  193. package/dist/esm/prover.d.ts +27 -4
  194. package/dist/esm/prover.js +106 -15
  195. package/dist/esm/relayer/api.d.ts +31 -0
  196. package/dist/esm/relayer/api.js +55 -0
  197. package/dist/esm/relayer/client.d.ts +29 -17
  198. package/dist/esm/relayer/client.js +72 -17
  199. package/dist/esm/relayer/errors.d.ts +1 -1
  200. package/dist/esm/relayer/errors.js +1 -1
  201. package/dist/esm/relayer/index.d.ts +4 -1
  202. package/dist/esm/relayer/index.js +1 -1
  203. package/dist/esm/relayer/internal-config.d.ts +36 -0
  204. package/dist/esm/relayer/internal-config.js +6 -0
  205. package/dist/esm/relayer/internal.d.ts +6 -0
  206. package/dist/esm/relayer/internal.js +10 -0
  207. package/dist/esm/relayer/transport.d.ts +4 -2
  208. package/dist/esm/relayer/transport.js +10 -5
  209. package/dist/esm/relayer/types.d.ts +9 -10
  210. package/dist/esm/relayer/types.js +1 -1
  211. package/dist/esm/shield/owner.js +1 -4
  212. package/identity.d.ts +2 -0
  213. package/identity.js +3 -0
  214. package/idl.d.ts +2 -0
  215. package/idl.js +3 -0
  216. package/notes.d.ts +2 -0
  217. package/notes.js +3 -0
  218. package/package.json +85 -3
  219. package/perps.d.ts +2 -0
  220. package/perps.js +3 -0
  221. package/poseidon.d.ts +2 -0
  222. package/poseidon.js +3 -0
  223. package/positions.d.ts +2 -0
  224. package/positions.js +3 -0
  225. package/predictions.d.ts +2 -0
  226. package/predictions.js +3 -0
  227. package/proof.d.ts +2 -0
  228. package/proof.js +3 -0
  229. package/prover.d.ts +2 -0
  230. package/prover.js +3 -0
  231. package/relayer.d.ts +2 -0
  232. package/relayer.js +3 -0
  233. package/shield.d.ts +2 -0
  234. package/shield.js +3 -0
  235. package/transactions.d.ts +2 -0
  236. package/transactions.js +3 -0
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getInternalRelayerClient = getInternalRelayerClient;
4
+ exports.createInternalRelayerClient = createInternalRelayerClient;
5
+ const client_js_1 = require("./client.js");
6
+ const RELAYER = new client_js_1.VeiloRelayerClient();
7
+ /** @internal Shared stateless production client for public SDK helpers. */
8
+ function getInternalRelayerClient() {
9
+ return RELAYER;
10
+ }
11
+ /** @internal Auth state is isolated per call to avoid cross-user token leaks. */
12
+ function createInternalRelayerClient(options = {}) {
13
+ return new client_js_1.VeiloRelayerClient(options);
14
+ }
@@ -1,4 +1,5 @@
1
- import type { RetryPolicy, VeiloRelayerConfig } from "./types.js";
1
+ import { type InternalRelayerClientOptions } from "./internal-config.js";
2
+ import type { RetryPolicy } from "./types.js";
2
3
  export interface RelayerRequestOptions {
3
4
  body?: unknown;
4
5
  authenticated?: boolean;
@@ -10,7 +11,8 @@ export declare class RelayerHttpTransport {
10
11
  private readonly apiKey;
11
12
  private authToken;
12
13
  private readonly retry;
13
- constructor(config: VeiloRelayerConfig, retry?: Partial<RetryPolicy>);
14
+ private readonly fetcher?;
15
+ constructor(config?: InternalRelayerClientOptions, retry?: Partial<RetryPolicy>);
14
16
  setAuthToken(token: string): void;
15
17
  request<T>(method: string, route: string, options?: RelayerRequestOptions): Promise<T>;
16
18
  private headers;
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RelayerHttpTransport = void 0;
4
4
  const errors_js_1 = require("./errors.js");
5
- const DEFAULT_RELAYER_URL = "https://relayer-server.onrender.com";
5
+ const internal_config_js_1 = require("./internal-config.js");
6
6
  const DEFAULT_RETRY = {
7
7
  maxRetries: 3,
8
8
  baseDelayMs: 1000,
@@ -10,11 +10,12 @@ const DEFAULT_RETRY = {
10
10
  };
11
11
  /** Owns HTTP authentication, retry, and response normalization. */
12
12
  class RelayerHttpTransport {
13
- constructor(config, retry) {
14
- this.baseUrl = (config.relayerUrl?.trim() || DEFAULT_RELAYER_URL).replace(/\/+$/, "");
15
- this.apiKey = config.apiKey;
13
+ constructor(config = {}, retry) {
14
+ this.baseUrl = (config.baseUrl?.trim() || internal_config_js_1.VEILO_RELAYER_URL).replace(/\/+$/, "");
15
+ this.apiKey = config.apiKey ?? "";
16
16
  this.authToken = config.authToken;
17
17
  this.retry = { ...DEFAULT_RETRY, ...retry };
18
+ this.fetcher = config.fetch;
18
19
  }
19
20
  setAuthToken(token) {
20
21
  this.authToken = token;
@@ -31,7 +32,11 @@ class RelayerHttpTransport {
31
32
  }
32
33
  let response;
33
34
  try {
34
- response = await fetch(url, {
35
+ const fetcher = this.fetcher ?? globalThis.fetch;
36
+ if (typeof fetcher !== "function") {
37
+ throw new Error("This environment does not provide fetch");
38
+ }
39
+ response = await fetcher(url, {
35
40
  method,
36
41
  headers: this.headers(authenticated),
37
42
  body: body == null ? undefined : JSON.stringify(body),
@@ -1,13 +1,3 @@
1
- export interface VeiloRelayerConfig {
2
- /** Base URL of the relayer. Defaults to Veilo's production service. */
3
- relayerUrl?: string;
4
- /** API key sent as x-api-key header */
5
- apiKey: string;
6
- /** Relayer's NaCl box public key (base64-encoded, 32 bytes) */
7
- relayerPublicKey: string;
8
- /** Optional JWT auth token for authenticated endpoints */
9
- authToken?: string;
10
- }
11
1
  /** Retry configuration for the relayer HTTP client. */
12
2
  export interface RetryPolicy {
13
3
  /** Max number of retry attempts (default: 3) */
@@ -49,6 +39,15 @@ export interface QueryNotesResponse {
49
39
  limit: number;
50
40
  offset: number;
51
41
  }
42
+ /** Nullifiers to test for spend status. Max 200 per request, 64-char hex. */
43
+ export interface CheckNullifiersRequest {
44
+ nullifiers: string[];
45
+ }
46
+ export interface CheckNullifiersResponse {
47
+ success: boolean;
48
+ /** The SPENT subset, lowercase hex. Absent entries are unspent. */
49
+ spent: string[];
50
+ }
52
51
  export interface SaveEncryptedNoteRequest {
53
52
  commitment: string;
54
53
  ephemeralPublicKey: string;
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  // =============================================================================
3
- // Configuration
3
+ // Retry Policy
4
4
  // =============================================================================
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -17,10 +17,7 @@ const errors_js_2 = require("./errors.js");
17
17
  * inspectable. The two owner endpoints used below are intentionally public and
18
18
  * return public key material only.
19
19
  */
20
- const OWNER_RELAYER = new client_js_1.VeiloRelayerClient({
21
- apiKey: "",
22
- relayerPublicKey: "utVxnA7zax09qJCZ7UJsa8PAOoWLRcCwOkdxg/ZGmD4=",
23
- });
20
+ const OWNER_RELAYER = new client_js_1.VeiloRelayerClient();
24
21
  /**
25
22
  * Resolve a shield recipient into the pair of keys that must belong to the same
26
23
  * account.
@@ -0,0 +1,6 @@
1
+ export * from "./types.js";
2
+ export * from "./parsing.js";
3
+ export * from "./position.js";
4
+ export * from "./recovery.js";
5
+ export * from "./scanning.js";
6
+ export * from "./tree.js";
@@ -0,0 +1,6 @@
1
+ export * from "./types.js";
2
+ export * from "./parsing.js";
3
+ export * from "./position.js";
4
+ export * from "./recovery.js";
5
+ export * from "./scanning.js";
6
+ export * from "./tree.js";
@@ -0,0 +1,25 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ import { type VersionedPrivacyPoolIdl } from "../idl/index.js";
3
+ import type { CommitmentEvent, NullifierSpentEvent, ParsedVeiloEvent } from "./types.js";
4
+ /**
5
+ * Decode logs using the current, legacy, and legacy-2 IDLs.
6
+ *
7
+ * IDLs are evaluated in the relayer's current/legacy/legacy-2 order. Anchor's
8
+ * Borsh decoder accepts trailing bytes, however, so every successful parse is
9
+ * considered and the richest result wins. That preserves the compact fields
10
+ * in legacy-2 events instead of misclassifying them as the shorter legacy form.
11
+ * Ties retain the relayer's order.
12
+ */
13
+ export declare function parseVeiloEventsWithFallback(logMessages: readonly string[] | null | undefined, programId: PublicKey, idls?: readonly VersionedPrivacyPoolIdl[]): ParsedVeiloEvent[];
14
+ export declare function parseCommitmentEventsFromLogs(params: {
15
+ logMessages: readonly string[] | null | undefined;
16
+ programId: PublicKey;
17
+ txSignature: string;
18
+ slot: number;
19
+ }): CommitmentEvent[];
20
+ export declare function parseNullifierEventsFromLogs(params: {
21
+ logMessages: readonly string[] | null | undefined;
22
+ programId: PublicKey;
23
+ txSignature: string;
24
+ slot: number;
25
+ }): NullifierSpentEvent[];
@@ -0,0 +1,120 @@
1
+ import * as anchor from "@coral-xyz/anchor";
2
+ import { PublicKey } from "@solana/web3.js";
3
+ import { PRIVACY_POOL_IDLS, } from "../idl/index.js";
4
+ /**
5
+ * Decode logs using the current, legacy, and legacy-2 IDLs.
6
+ *
7
+ * IDLs are evaluated in the relayer's current/legacy/legacy-2 order. Anchor's
8
+ * Borsh decoder accepts trailing bytes, however, so every successful parse is
9
+ * considered and the richest result wins. That preserves the compact fields
10
+ * in legacy-2 events instead of misclassifying them as the shorter legacy form.
11
+ * Ties retain the relayer's order.
12
+ */
13
+ export function parseVeiloEventsWithFallback(logMessages, programId, idls = PRIVACY_POOL_IDLS) {
14
+ if (!logMessages?.length)
15
+ return [];
16
+ let best = [];
17
+ let bestScore = -1;
18
+ for (const candidate of idls) {
19
+ try {
20
+ const parser = new anchor.EventParser(programId, new anchor.BorshCoder(candidate.idl));
21
+ const parsed = Array.from(parser.parseLogs([...logMessages])).map((event) => ({
22
+ name: event.name,
23
+ data: event.data,
24
+ idlVersion: candidate.version,
25
+ }));
26
+ const score = parsed.reduce((total, event) => total + decodedFieldCount(event.data), 0);
27
+ if (score > bestScore) {
28
+ best = parsed;
29
+ bestScore = score;
30
+ }
31
+ }
32
+ catch {
33
+ // The discriminator is shared while historical payload lengths differ.
34
+ }
35
+ }
36
+ return best;
37
+ }
38
+ export function parseCommitmentEventsFromLogs(params) {
39
+ const { logMessages, programId, txSignature, slot } = params;
40
+ const out = [];
41
+ for (const event of parseVeiloEventsWithFallback(logMessages, programId)) {
42
+ if (event.name.toLowerCase() !== "commitmentevent")
43
+ continue;
44
+ const data = event.data;
45
+ const mintAddress = toPublicKey(field(data, "mintAddress", "mint_address"));
46
+ const ephemeralPublicKey = optionalBytes(field(data, "ephemeralPublicKey", "ephemeral_public_key"));
47
+ const encryptedBlob = optionalBytes(field(data, "encryptedBlob", "encrypted_blob"));
48
+ const rawViewTag = field(data, "viewTag", "view_tag");
49
+ out.push({
50
+ commitment: toBytes(field(data, "commitment"), 32, "commitment"),
51
+ leafIndex: toSafeNumber(field(data, "leafIndex", "leaf_index"), "leafIndex"),
52
+ newRoot: toBytes(field(data, "newRoot", "new_root"), 32, "newRoot"),
53
+ timestamp: toSafeNumber(field(data, "timestamp"), "timestamp"),
54
+ mintAddress,
55
+ treeId: toSafeNumber(field(data, "treeId", "tree_id"), "treeId"),
56
+ txSignature,
57
+ slot,
58
+ ...(ephemeralPublicKey ? { ephemeralPublicKey } : {}),
59
+ ...(encryptedBlob ? { encryptedBlob } : {}),
60
+ ...(rawViewTag !== undefined
61
+ ? { viewTag: toSafeNumber(rawViewTag, "viewTag") }
62
+ : {}),
63
+ source: "emitted",
64
+ idlVersion: event.idlVersion,
65
+ });
66
+ }
67
+ return out;
68
+ }
69
+ export function parseNullifierEventsFromLogs(params) {
70
+ const { logMessages, programId, txSignature, slot } = params;
71
+ const out = [];
72
+ for (const event of parseVeiloEventsWithFallback(logMessages, programId)) {
73
+ if (event.name.toLowerCase() !== "nullifierspent")
74
+ continue;
75
+ const data = event.data;
76
+ out.push({
77
+ nullifier: toBytes(field(data, "nullifier"), 32, "nullifier"),
78
+ timestamp: toSafeNumber(field(data, "timestamp"), "timestamp"),
79
+ mintAddress: toPublicKey(field(data, "mintAddress", "mint_address")),
80
+ treeId: toSafeNumber(field(data, "treeId", "tree_id"), "treeId"),
81
+ txSignature,
82
+ slot,
83
+ idlVersion: event.idlVersion,
84
+ });
85
+ }
86
+ return out;
87
+ }
88
+ function field(data, camel, snake) {
89
+ return data[camel] ?? (snake ? data[snake] : undefined);
90
+ }
91
+ function optionalBytes(value) {
92
+ return value === undefined || value === null
93
+ ? undefined
94
+ : new Uint8Array(value);
95
+ }
96
+ function decodedFieldCount(value) {
97
+ return value && typeof value === "object" ? Object.keys(value).length : 0;
98
+ }
99
+ function toBytes(value, length, label) {
100
+ const bytes = new Uint8Array(value);
101
+ if (bytes.length !== length) {
102
+ throw new Error(`${label} must be ${length} bytes, got ${bytes.length}`);
103
+ }
104
+ return bytes;
105
+ }
106
+ function toPublicKey(value) {
107
+ if (value instanceof PublicKey)
108
+ return value;
109
+ return new PublicKey(value);
110
+ }
111
+ function toSafeNumber(value, label) {
112
+ if (value === undefined || value === null) {
113
+ throw new Error(`Missing ${label} in decoded event`);
114
+ }
115
+ const numeric = typeof value === "number" ? value : Number(value);
116
+ if (!Number.isSafeInteger(numeric)) {
117
+ throw new Error(`${label} is outside JavaScript's safe integer range`);
118
+ }
119
+ return numeric;
120
+ }
@@ -0,0 +1,26 @@
1
+ import type { Idl, Program } from "@coral-xyz/anchor";
2
+ import { PublicKey } from "@solana/web3.js";
3
+ import type { CommitmentEvent } from "./types.js";
4
+ /**
5
+ * Privacy-pool mints copied from the relayer's global position-tree classifier.
6
+ * Position commitments use non-pool destination mints at the same tree ID.
7
+ */
8
+ export declare const POSITION_TREE_POOL_MINTS: readonly PublicKey[];
9
+ export declare function isGlobalPositionCommitment(event: CommitmentEvent): boolean;
10
+ /**
11
+ * Rebuild the one global position tree shared across every position mint.
12
+ * This mirrors the relayer: scan all mints for the position tree ID, then drop
13
+ * normal privacy-pool mint events before sorting by the global leaf index.
14
+ */
15
+ export declare function buildGlobalPositionTreeFromEvents<T extends Idl>(params: {
16
+ program: Program<T>;
17
+ positionTreeId?: number;
18
+ depth?: number;
19
+ additionalEvents?: readonly CommitmentEvent[];
20
+ includeProtectedEvents?: boolean;
21
+ strictLeafIndices?: boolean;
22
+ }): Promise<{
23
+ tree: import("../merkle.js").MerkleTree;
24
+ events: CommitmentEvent[];
25
+ latestSignature: string;
26
+ }>;
@@ -0,0 +1,48 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ import { getAllProtectedCommitmentEvents } from "./recovery.js";
3
+ import { scanAllCommitmentEvents } from "./scanning.js";
4
+ import { dedupeCommitmentEvents, reconstructTreeFromCommitmentEvents, } from "./tree.js";
5
+ /**
6
+ * Privacy-pool mints copied from the relayer's global position-tree classifier.
7
+ * Position commitments use non-pool destination mints at the same tree ID.
8
+ */
9
+ export const POSITION_TREE_POOL_MINTS = [
10
+ PublicKey.default,
11
+ new PublicKey("So11111111111111111111111111111111111111112"),
12
+ new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"),
13
+ new PublicKey("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"),
14
+ new PublicKey("USD1ttGY1N17NEEHLmELoaybftRBUSErhqYiQzvEmuB"),
15
+ new PublicKey("JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN"),
16
+ new PublicKey("ARXwZkNAtzPfdcoqQiduJn8EPv9fKiDfGn2KyggyDrFs"),
17
+ ];
18
+ const POOL_MINTS = new Set(POSITION_TREE_POOL_MINTS.map((mint) => mint.toBase58()));
19
+ export function isGlobalPositionCommitment(event) {
20
+ return !POOL_MINTS.has(event.mintAddress.toBase58());
21
+ }
22
+ /**
23
+ * Rebuild the one global position tree shared across every position mint.
24
+ * This mirrors the relayer: scan all mints for the position tree ID, then drop
25
+ * normal privacy-pool mint events before sorting by the global leaf index.
26
+ */
27
+ export async function buildGlobalPositionTreeFromEvents(params) {
28
+ const { program, positionTreeId = 0, depth = 22, additionalEvents = [], includeProtectedEvents = true, strictLeafIndices = true, } = params;
29
+ const emitted = await scanAllCommitmentEvents({ program });
30
+ const protectedEvents = includeProtectedEvents
31
+ ? getAllProtectedCommitmentEvents()
32
+ : [];
33
+ const events = dedupeCommitmentEvents([
34
+ ...emitted,
35
+ ...additionalEvents,
36
+ ...protectedEvents,
37
+ ])
38
+ .filter((event) => event.treeId === positionTreeId && isGlobalPositionCommitment(event))
39
+ .sort((a, b) => a.leafIndex - b.leafIndex);
40
+ return {
41
+ tree: reconstructTreeFromCommitmentEvents(events, {
42
+ depth,
43
+ strictLeafIndices,
44
+ }),
45
+ events,
46
+ latestSignature: events[events.length - 1]?.txSignature,
47
+ };
48
+ }
@@ -0,0 +1,87 @@
1
+ import type { Connection } from "@solana/web3.js";
2
+ import { PublicKey } from "@solana/web3.js";
3
+ import { MerkleTree } from "../merkle.js";
4
+ import type { CommitmentEvent } from "./types.js";
5
+ /**
6
+ * Historical leaves repaired manually in the relayer.
7
+ *
8
+ * The deployed `open_position` instruction appended these commitments without
9
+ * emitting CommitmentEvent. They must be retained when rebuilding history.
10
+ * Values are copied byte-for-byte from relayer-server/src/db/service.ts.
11
+ */
12
+ export declare const PROTECTED_COMMITMENT_EVENTS: readonly [{
13
+ readonly leafIndex: 3738;
14
+ readonly commitmentHex: "0c7850c9360e041ceeba27297e0fd49fa6a224a651c2fff8c56b22c70a319a94";
15
+ }, {
16
+ readonly leafIndex: 4;
17
+ readonly commitmentHex: "15e182d12e044ef2a469ccda88d903304a4e3e69f72765a29e4e6df9c206b0bf";
18
+ readonly mintAddressHex: "e272b88fb18eaf1994acb885bdba76820c567c3467300f0cd320a0c15ebf9d2f";
19
+ readonly onChainTreeId: 0;
20
+ }];
21
+ /** @deprecated Use PROTECTED_COMMITMENT_EVENTS. */
22
+ export declare const PROTECTED_COMMITMENT_EVENT: {
23
+ readonly leafIndex: 3738;
24
+ readonly commitmentHex: "0c7850c9360e041ceeba27297e0fd49fa6a224a651c2fff8c56b22c70a319a94";
25
+ };
26
+ /** Return protected records as normal SDK events for a particular tree. */
27
+ export declare function getProtectedCommitmentEvents(params: {
28
+ mintAddress: PublicKey;
29
+ treeId?: number;
30
+ }): CommitmentEvent[];
31
+ /** Return every protected leaf, including the global position-tree repair. */
32
+ export declare function getAllProtectedCommitmentEvents(): CommitmentEvent[];
33
+ /**
34
+ * Add the protected historical leaves without duplicating records already read
35
+ * from an indexer. A conflicting commitment at a protected index is rejected.
36
+ */
37
+ export declare function mergeProtectedCommitmentEvents(events: readonly CommitmentEvent[], params: {
38
+ mintAddress: PublicKey;
39
+ treeId?: number;
40
+ }): CommitmentEvent[];
41
+ /**
42
+ * Insert expected commitments and prefer authoritative emitted metadata when it
43
+ * exists. Missing events are computed from the local tree exactly like the
44
+ * relayer's `insertAndPersistCommitments` fallback.
45
+ *
46
+ * This function mutates `tree`.
47
+ */
48
+ export declare function resolveCommitmentEvents(params: {
49
+ commitments: readonly Uint8Array[];
50
+ tree: MerkleTree;
51
+ logMessages?: readonly string[] | null;
52
+ programId: PublicKey;
53
+ mintAddress: PublicKey;
54
+ treeId: number;
55
+ txSignature: string;
56
+ slot: number;
57
+ timestamp?: number;
58
+ requireAllInLogs?: boolean;
59
+ }): CommitmentEvent[];
60
+ export type EventlessOpenPositionCommitments = {
61
+ sourceMint: PublicKey;
62
+ sourceTreeId: number;
63
+ sourceCommitment: Uint8Array;
64
+ positionMint: PublicKey;
65
+ positionTreeId: number;
66
+ positionCommitment: Uint8Array;
67
+ positionPdaKey: Uint8Array;
68
+ };
69
+ /** Decode the two commitments hidden in a current `open_position` instruction. */
70
+ export declare function decodeEventlessOpenPositionCommitments(instructionData: Uint8Array): EventlessOpenPositionCommitments | null;
71
+ export declare function getPositionPda(programId: PublicKey, positionPdaKey: Uint8Array): PublicKey;
72
+ /** Read PositionPDA.leaf_index at the same byte offset used by the relayer. */
73
+ export declare function readPositionLeafIndex(accountData: Uint8Array): number;
74
+ /**
75
+ * Recover the two events omitted by the deployed `open_position` instruction.
76
+ * The source tree must already contain every earlier source-mint commitment.
77
+ * This function inserts the source commitment into that tree.
78
+ */
79
+ export declare function recoverEventlessOpenPositionEvents(params: {
80
+ instructionData: Uint8Array;
81
+ sourceTree: MerkleTree;
82
+ connection: Pick<Connection, "getAccountInfo">;
83
+ programId: PublicKey;
84
+ txSignature: string;
85
+ slot: number;
86
+ timestamp?: number;
87
+ }): Promise<CommitmentEvent[]>;