@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,141 @@
1
+ import { VersionedTransaction } from "@solana/web3.js";
2
+ export const JUPITER_PREDICTION_API_URL = "https://api.jup.ag/prediction/v1";
3
+ export const POLYMARKET_CLOB_API_URL = "https://clob.polymarket.com";
4
+ export class JupiterPredictionApiError extends Error {
5
+ constructor(status, responseBody) {
6
+ const body = typeof responseBody === "object" && responseBody !== null
7
+ ? responseBody
8
+ : undefined;
9
+ const message = typeof responseBody === "string" && responseBody
10
+ ? responseBody
11
+ : typeof body?.message === "string"
12
+ ? body.message
13
+ : typeof body?.error === "string"
14
+ ? body.error
15
+ : `Jupiter Prediction API request failed: ${status}`;
16
+ super(message);
17
+ this.name = "JupiterPredictionApiError";
18
+ this.status = status;
19
+ this.code = typeof body?.error === "string" ? body.error : undefined;
20
+ this.responseBody = responseBody;
21
+ }
22
+ }
23
+ /** Typed client for the unsigned Jupiter Prediction transaction API. */
24
+ export class JupiterPredictionClient {
25
+ constructor(config) {
26
+ this.apiKey = config.apiKey;
27
+ this.baseUrl = normalizeBaseUrl(config.baseUrl ?? JUPITER_PREDICTION_API_URL, "baseUrl");
28
+ this.polymarketBaseUrl = normalizeBaseUrl(config.polymarketBaseUrl ?? POLYMARKET_CLOB_API_URL, "polymarketBaseUrl");
29
+ this.fetcher = config.fetch ?? fetch;
30
+ }
31
+ async listEvents(params = {}) {
32
+ const query = new URLSearchParams({ status: params.status ?? "live" });
33
+ if (params.category)
34
+ query.set("category", params.category);
35
+ return (await this.request(`/events?${query}`)).data;
36
+ }
37
+ async getEvent(eventId) {
38
+ return this.request(`/events/${encodeURIComponent(eventId)}`);
39
+ }
40
+ async listPositions(ownerPubkey) {
41
+ return (await this.request(`/positions?ownerPubkey=${encodeURIComponent(ownerPubkey)}`)).data;
42
+ }
43
+ async listHistory(ownerPubkey) {
44
+ return (await this.request(`/history?ownerPubkey=${encodeURIComponent(ownerPubkey)}`)).data;
45
+ }
46
+ async getPosition(positionPubkey) {
47
+ return this.request(`/positions/${encodeURIComponent(positionPubkey)}`);
48
+ }
49
+ async placeOrder(request) {
50
+ return this.request("/orders", { method: "POST", body: request });
51
+ }
52
+ async getOrderStatus(orderPubkey) {
53
+ return this.request(`/orders/status/${encodeURIComponent(orderPubkey)}`);
54
+ }
55
+ async closePosition(positionPubkey, ownerPubkey) {
56
+ return this.request(`/positions/${encodeURIComponent(positionPubkey)}`, {
57
+ method: "DELETE",
58
+ body: { ownerPubkey },
59
+ });
60
+ }
61
+ async closeAllPositions(ownerPubkey, minSellPriceSlippageBps = 300) {
62
+ return this.request("/positions", {
63
+ method: "DELETE",
64
+ body: { ownerPubkey, minSellPriceSlippageBps },
65
+ });
66
+ }
67
+ async claimPosition(positionPubkey, ownerPubkey) {
68
+ return this.request(`/positions/${encodeURIComponent(positionPubkey)}/claim`, { method: "POST", body: { ownerPubkey } });
69
+ }
70
+ async getPriceHistory(clobTokenId, interval) {
71
+ const fidelity = {
72
+ "1d": 5,
73
+ "1w": 30,
74
+ "1m": 180,
75
+ max: 180,
76
+ };
77
+ const query = new URLSearchParams({
78
+ market: clobTokenId,
79
+ interval,
80
+ fidelity: String(fidelity[interval]),
81
+ });
82
+ const response = await this.fetcher(`${this.polymarketBaseUrl}/prices-history?${query}`);
83
+ const body = await readResponseBody(response);
84
+ if (!response.ok) {
85
+ throw new JupiterPredictionApiError(response.status, body);
86
+ }
87
+ return body.history ?? [];
88
+ }
89
+ async request(path, options = {}) {
90
+ const response = await this.fetcher(`${this.baseUrl}${path}`, {
91
+ method: options.method ?? "GET",
92
+ headers: {
93
+ "x-api-key": this.apiKey,
94
+ ...(options.body === undefined
95
+ ? {}
96
+ : { "Content-Type": "application/json" }),
97
+ },
98
+ body: options.body === undefined ? undefined : JSON.stringify(options.body),
99
+ });
100
+ const body = await readResponseBody(response);
101
+ if (!response.ok) {
102
+ throw new JupiterPredictionApiError(response.status, body);
103
+ }
104
+ return body;
105
+ }
106
+ }
107
+ /** Decode an unsigned transaction returned by Jupiter for wallet signing. */
108
+ export function deserializePredictionTransaction(response) {
109
+ if (!response.transaction) {
110
+ throw new TypeError("Prediction transaction must not be empty");
111
+ }
112
+ return VersionedTransaction.deserialize(decodeBase64(response.transaction));
113
+ }
114
+ function normalizeBaseUrl(value, label) {
115
+ const normalized = value.trim().replace(/\/+$/, "");
116
+ if (!normalized)
117
+ throw new TypeError(`${label} must not be empty`);
118
+ return normalized;
119
+ }
120
+ async function readResponseBody(response) {
121
+ const body = await response.text();
122
+ if (!body)
123
+ return {};
124
+ try {
125
+ return JSON.parse(body);
126
+ }
127
+ catch {
128
+ return body;
129
+ }
130
+ }
131
+ function decodeBase64(encoded) {
132
+ if (typeof Buffer !== "undefined") {
133
+ return new Uint8Array(Buffer.from(encoded, "base64"));
134
+ }
135
+ const binary = atob(encoded);
136
+ const bytes = new Uint8Array(binary.length);
137
+ for (let index = 0; index < binary.length; index++) {
138
+ bytes[index] = binary.charCodeAt(index);
139
+ }
140
+ return bytes;
141
+ }
@@ -0,0 +1,5 @@
1
+ export * from "./types.js";
2
+ export * from "./keys.js";
3
+ export * from "./pdas.js";
4
+ export * from "./client.js";
5
+ export * from "./relayer.js";
@@ -0,0 +1,5 @@
1
+ export * from "./types.js";
2
+ export * from "./keys.js";
3
+ export * from "./pdas.js";
4
+ export * from "./client.js";
5
+ export * from "./relayer.js";
@@ -0,0 +1,14 @@
1
+ import { Keypair } from "@solana/web3.js";
2
+ export interface PredictionKeyBundle {
3
+ withdrawalId: Uint8Array;
4
+ withdrawalIdHex: string;
5
+ ephemeral: Keypair;
6
+ claimantPublicKey: string;
7
+ claimantSecretKey: string;
8
+ }
9
+ export declare function derivePredictionEphemeralKeypair(spendingKey: Uint8Array, nonce: number): Keypair;
10
+ export declare function derivePredictionWithdrawalId(spendingKey: Uint8Array, nonce: number): Uint8Array;
11
+ export declare function predictionWithdrawalIdToHex(withdrawalId: Uint8Array): string;
12
+ export declare function predictionWithdrawalIdFromHex(value: string): Uint8Array;
13
+ /** Derive every client-held key field needed across a prediction lifecycle. */
14
+ export declare function derivePredictionKeyBundle(spendingKey: Uint8Array, nonce: number): PredictionKeyBundle;
@@ -0,0 +1,33 @@
1
+ import { sha256 } from "@noble/hashes/sha256";
2
+ import { Keypair } from "@solana/web3.js";
3
+ import { assertBytes, bytesToHex, concatBytes, encodeBase58, hexToBytes, uint32Le, uint64Le, utf8, } from "../identity/encoding.js";
4
+ export function derivePredictionEphemeralKeypair(spendingKey, nonce) {
5
+ assertBytes(spendingKey, 32, "spending key");
6
+ if (!Number.isSafeInteger(nonce) || nonce < 0) {
7
+ throw new RangeError("prediction nonce must be a non-negative safe integer");
8
+ }
9
+ return Keypair.fromSeed(sha256(concatBytes(utf8("prediction_ephemeral"), spendingKey, uint64Le(BigInt(nonce), "prediction nonce"))));
10
+ }
11
+ export function derivePredictionWithdrawalId(spendingKey, nonce) {
12
+ assertBytes(spendingKey, 32, "spending key");
13
+ return sha256(concatBytes(utf8("prediction_withdrawal_v1"), spendingKey, uint32Le(nonce, "prediction nonce")));
14
+ }
15
+ export function predictionWithdrawalIdToHex(withdrawalId) {
16
+ assertBytes(withdrawalId, 32, "prediction withdrawal ID");
17
+ return bytesToHex(withdrawalId);
18
+ }
19
+ export function predictionWithdrawalIdFromHex(value) {
20
+ return hexToBytes(value, 32, "prediction withdrawal ID");
21
+ }
22
+ /** Derive every client-held key field needed across a prediction lifecycle. */
23
+ export function derivePredictionKeyBundle(spendingKey, nonce) {
24
+ const withdrawalId = derivePredictionWithdrawalId(spendingKey, nonce);
25
+ const ephemeral = derivePredictionEphemeralKeypair(spendingKey, nonce);
26
+ return {
27
+ withdrawalId,
28
+ withdrawalIdHex: predictionWithdrawalIdToHex(withdrawalId),
29
+ ephemeral,
30
+ claimantPublicKey: ephemeral.publicKey.toBase58(),
31
+ claimantSecretKey: encodeBase58(ephemeral.secretKey),
32
+ };
33
+ }
@@ -0,0 +1,6 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ export declare function derivePredictionSlotPda(params: {
3
+ programId: PublicKey;
4
+ mint: PublicKey;
5
+ withdrawalId: Uint8Array;
6
+ }): PublicKey;
@@ -0,0 +1,10 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ import { assertBytes, utf8 } from "../identity/encoding.js";
3
+ export function derivePredictionSlotPda(params) {
4
+ assertBytes(params.withdrawalId, 32, "prediction withdrawal ID");
5
+ return PublicKey.findProgramAddressSync([
6
+ utf8("prediction_slot_v1"),
7
+ params.mint.toBytes(),
8
+ params.withdrawalId,
9
+ ], params.programId)[0];
10
+ }
@@ -0,0 +1,3 @@
1
+ import type { PredictionOpenRequest, PredictionOpenResponse, PredictionReissueRequest, PredictionReissueResponse } from "./types.js";
2
+ export declare function submitPredictionOpen(data: PredictionOpenRequest): Promise<PredictionOpenResponse>;
3
+ export declare function submitPredictionReissue(data: PredictionReissueRequest): Promise<PredictionReissueResponse>;
@@ -0,0 +1,7 @@
1
+ import { getInternalRelayerClient } from "../relayer/internal.js";
2
+ export function submitPredictionOpen(data) {
3
+ return getInternalRelayerClient().submitPredictionOpen(data);
4
+ }
5
+ export function submitPredictionReissue(data) {
6
+ return getInternalRelayerClient().submitPredictionReissue(data);
7
+ }
@@ -0,0 +1,178 @@
1
+ import type { TransactNote } from "../relayer/types.js";
2
+ export interface PredictionOpenRequest {
3
+ notes: TransactNote[];
4
+ /** USDC stake, raw 6-decimal units. */
5
+ depositAmount: string;
6
+ /** 32-byte prediction-slot withdrawal ID, hex. */
7
+ withdrawalId: string;
8
+ /** Deterministic ephemeral wallet and open-proof claimant, base58. */
9
+ claimantPublicKey: string;
10
+ userPublicKey: string;
11
+ }
12
+ export interface PredictionOpenResponse {
13
+ success: boolean;
14
+ message: string;
15
+ data?: {
16
+ txSignature: string;
17
+ ephemeralWallet: string;
18
+ ephemeralTokenAccount: string;
19
+ changeAmount: string;
20
+ fee: string;
21
+ feeBps: number;
22
+ totalDebited: string;
23
+ };
24
+ }
25
+ export interface PredictionReissueRequest {
26
+ withdrawalId: string;
27
+ claimantSecretKey: string;
28
+ /** Kept for API compatibility; the relayer reads the real chain balance. */
29
+ reissueAmount: string;
30
+ veiloPublicKey: string;
31
+ userPublicKey: string;
32
+ }
33
+ export interface PredictionReissueResponse {
34
+ success: boolean;
35
+ message: string;
36
+ data?: {
37
+ txSignature: string | null;
38
+ reissueAmount: string;
39
+ fee?: string;
40
+ tradeHappened?: boolean;
41
+ };
42
+ }
43
+ export interface PredictionMarketPricing {
44
+ buyYesPriceUsd: number;
45
+ sellYesPriceUsd: number;
46
+ buyNoPriceUsd: number;
47
+ sellNoPriceUsd: number;
48
+ volume: number;
49
+ }
50
+ export interface PredictionMarket {
51
+ provider: string;
52
+ marketId: string;
53
+ status: "open" | "closed" | "cancelled";
54
+ result: string | null;
55
+ title: string;
56
+ openTime: number;
57
+ closeTime: number;
58
+ rulesPrimary?: string;
59
+ imageUrl?: string;
60
+ clobTokenIds?: string[];
61
+ pricing: PredictionMarketPricing;
62
+ }
63
+ export interface PredictionEvent {
64
+ eventId: string;
65
+ isActive: boolean;
66
+ isLive: boolean;
67
+ category: string;
68
+ subcategory: string;
69
+ tags: string[];
70
+ metadata: {
71
+ title: string;
72
+ closeTime: string;
73
+ imageUrl?: string;
74
+ series?: string;
75
+ slug?: string;
76
+ };
77
+ volumeUsd: string;
78
+ volume24hr: string;
79
+ closeCondition?: string;
80
+ markets: PredictionMarket[];
81
+ }
82
+ export interface PredictionPosition {
83
+ pubkey: string;
84
+ owner: string;
85
+ marketId: string;
86
+ isYes: boolean;
87
+ contracts: string;
88
+ contractsDecimal: string;
89
+ totalCostUsd: string;
90
+ sizeUsd: string;
91
+ valueUsd: string;
92
+ avgPriceUsd: string;
93
+ markPriceUsd: string;
94
+ pnlUsd: string;
95
+ pnlUsdPercent: number;
96
+ feesPaidUsd: string;
97
+ claimed: boolean;
98
+ claimable: boolean;
99
+ payoutUsd: string;
100
+ sellPriceUsd: string;
101
+ settlementDate: number;
102
+ eventMetadata: {
103
+ title: string;
104
+ category: string;
105
+ imageUrl?: string;
106
+ };
107
+ marketMetadata: {
108
+ title: string;
109
+ result: string | null;
110
+ status: string;
111
+ };
112
+ }
113
+ export interface PlacePredictionOrderRequest {
114
+ ownerPubkey: string;
115
+ marketId: string;
116
+ isYes: boolean;
117
+ isBuy: true;
118
+ depositAmount: string;
119
+ depositMint: string;
120
+ }
121
+ export interface PredictionTransactionResponse {
122
+ transaction: string;
123
+ txMeta: {
124
+ blockhash: string;
125
+ lastValidBlockHeight: number;
126
+ };
127
+ }
128
+ export interface PlacePredictionOrderResponse extends PredictionTransactionResponse {
129
+ order: {
130
+ orderPubkey: string;
131
+ positionPubkey: string;
132
+ contracts: number;
133
+ };
134
+ }
135
+ export type PredictionOrderStatus = "pending" | "filled" | "partiallyfilled" | "failed";
136
+ export interface PredictionOrderStatusResponse {
137
+ orderPubkey: string;
138
+ status: PredictionOrderStatus;
139
+ latestEventType: string;
140
+ latestSignature: string;
141
+ history: Array<{
142
+ eventType: string;
143
+ status: string;
144
+ rawStatus: string;
145
+ timestamp: number;
146
+ signature: string;
147
+ }>;
148
+ }
149
+ export interface PredictionHistoryEvent {
150
+ id: number;
151
+ eventType: string;
152
+ signature: string;
153
+ timestamp: number;
154
+ marketId: string;
155
+ isYes: boolean;
156
+ isBuy: boolean;
157
+ contractsDecimal: string;
158
+ avgFillPriceUsd?: string;
159
+ totalCostUsd?: string;
160
+ netProceedsUsd?: string;
161
+ realizedPnl?: string;
162
+ payoutAmountUsd?: string;
163
+ eventMetadata: {
164
+ title: string;
165
+ category?: string;
166
+ imageUrl?: string;
167
+ };
168
+ marketMetadata: {
169
+ title: string;
170
+ result: string | null;
171
+ status: string;
172
+ };
173
+ }
174
+ export type PredictionPriceInterval = "1d" | "1w" | "1m" | "max";
175
+ export interface PredictionPricePoint {
176
+ t: number;
177
+ p: number;
178
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,6 +1,8 @@
1
1
  import { Program, Idl, Wallet } from "@coral-xyz/anchor";
2
2
  import { Connection, PublicKey } from "@solana/web3.js";
3
+ import { PRIVACY_POOL_CURRENT_IDL, PRIVACY_POOL_IDLS, PRIVACY_POOL_LEGACY2_IDL, PRIVACY_POOL_LEGACY_IDL } from "./idl/index.js";
3
4
  export declare const PRIVACY_POOL_IDL: Idl;
5
+ export { PRIVACY_POOL_CURRENT_IDL, PRIVACY_POOL_IDLS, PRIVACY_POOL_LEGACY_IDL, PRIVACY_POOL_LEGACY2_IDL, };
4
6
  /** Deployed program ID extracted from the bundled IDL. */
5
7
  export declare const PRIVACY_POOL_PROGRAM_ID: PublicKey;
6
8
  /**
@@ -1,10 +1,11 @@
1
1
  import { Program, AnchorProvider } from "@coral-xyz/anchor";
2
2
  import { PublicKey } from "@solana/web3.js";
3
- import IDL_JSON from "./idl/privacy_pool.js";
3
+ import { PRIVACY_POOL_CURRENT_IDL, PRIVACY_POOL_IDLS, PRIVACY_POOL_LEGACY2_IDL, PRIVACY_POOL_LEGACY_IDL, } from "./idl/index.js";
4
4
  // Re-export so consumers can access the raw IDL if needed
5
- export const PRIVACY_POOL_IDL = IDL_JSON;
5
+ export const PRIVACY_POOL_IDL = PRIVACY_POOL_CURRENT_IDL;
6
+ export { PRIVACY_POOL_CURRENT_IDL, PRIVACY_POOL_IDLS, PRIVACY_POOL_LEGACY_IDL, PRIVACY_POOL_LEGACY2_IDL, };
6
7
  /** Deployed program ID extracted from the bundled IDL. */
7
- export const PRIVACY_POOL_PROGRAM_ID = new PublicKey(IDL_JSON.address);
8
+ export const PRIVACY_POOL_PROGRAM_ID = new PublicKey(PRIVACY_POOL_CURRENT_IDL.address);
8
9
  /**
9
10
  * Create an Anchor `Program` instance for the Veilo Privacy Pool.
10
11
  *
@@ -3,8 +3,10 @@ import { type SwapProofBuilder } from "./proofs/swap.js";
3
3
  /**
4
4
  * Circuit artifact paths required by snarkjs.
5
5
  *
6
- * These files are large (10-100 MB) and should NOT be bundled in npm.
7
- * Host them on GitHub Releases, IPFS, or a CDN and download at runtime.
6
+ * These files are large (10-100 MB) and are NOT bundled in the npm package —
7
+ * `files` ships `dist/` only. Optional: omit them and the prover resolves a
8
+ * local copy (see `resolveCircuitArtifacts`). Supply them explicitly whenever
9
+ * the defaults cannot apply, which includes every browser build.
8
10
  *
9
11
  * For Node.js: pass file system paths (e.g. "./circuits/transaction.wasm").
10
12
  * For browsers: pass Uint8Array buffers or URLs that fetch returns as ArrayBuffer.
@@ -15,6 +17,27 @@ export interface CircuitArtifacts {
15
17
  /** Path or buffer for the Groth16 proving key (.zkey) */
16
18
  zkeyPath: string | Uint8Array;
17
19
  }
20
+ /** The circuits this package can resolve artifacts for. */
21
+ export type CircuitName = "transaction" | "swap";
22
+ /**
23
+ * Resolve circuit artifacts from disk when the caller did not supply them.
24
+ *
25
+ * Search order, first hit wins:
26
+ *
27
+ * 1. $VEILO_CIRCUITS_DIR explicit override
28
+ * 2. <package>/circuits populated by `npm run copy:circuits`
29
+ * 3. <cwd>/circuits
30
+ * 4. <cwd>/node_modules/@veilo/sdk-core/circuits
31
+ *
32
+ * NODE ONLY, AND DELIBERATELY LAZY. `node:fs` is imported inside the call, not
33
+ * at module scope: this module is reachable from the package root export, and a
34
+ * top-level `node:fs` import throws at bundle time in browser builds with no
35
+ * Node polyfill — the same reason `random.ts` avoids `node:crypto`. Browsers
36
+ * must pass `CircuitArtifacts` explicitly; there is nothing to resolve there.
37
+ *
38
+ * @throws when no candidate directory holds both files, listing what it tried
39
+ */
40
+ export declare function resolveCircuitArtifacts(circuit: CircuitName): Promise<CircuitArtifacts>;
18
41
  /**
19
42
  * Create a proof builder function for the transaction circuit.
20
43
  *
@@ -41,9 +64,9 @@ export interface CircuitArtifacts {
41
64
  * const proof = await prover(circuitInputs);
42
65
  * ```
43
66
  */
44
- export declare function createTransactionProver(artifacts: CircuitArtifacts): TransactionProofBuilder;
67
+ export declare function createTransactionProver(artifacts?: CircuitArtifacts): TransactionProofBuilder;
45
68
  /** Create a proof builder for the current `swap.circom` witness shape. */
46
- export declare function createSwapProver(artifacts: CircuitArtifacts): SwapProofBuilder;
69
+ export declare function createSwapProver(artifacts?: CircuitArtifacts): SwapProofBuilder;
47
70
  /**
48
71
  * Verify a Groth16 proof against public signals and a verification key.
49
72
  *
@@ -1,14 +1,91 @@
1
1
  import { formatInputsForSnarkjs } from "./proofs/formatting.js";
2
2
  import { formatSwapInputsForSnarkjs, } from "./proofs/swap.js";
3
- /** Lazy-load snarkjs — works in both CJS and ESM contexts. */
4
- async function loadSnarkjs() {
3
+ /**
4
+ * Lazy-load snarkjs — works in both CJS and ESM contexts.
5
+ *
6
+ * The import is built through `Function` so TypeScript cannot rewrite it into a
7
+ * `require()` in the CommonJS build, and bundlers cannot follow it into browser
8
+ * output. Never call `require("snarkjs")` directly here: `require` is not
9
+ * defined in the ESM build, so it throws ReferenceError instead of this
10
+ * message.
11
+ */
12
+ async function loadSnarkjs(purpose = "proof generation") {
5
13
  try {
6
14
  // Dynamic import works in both CJS (Node 12+) and ESM
7
15
  return await Function('return import("snarkjs")')();
8
16
  }
9
17
  catch {
10
- throw new Error("snarkjs is required for proof generation. Install it: npm install snarkjs");
18
+ throw new Error(`snarkjs is required for ${purpose}. Install it: npm install snarkjs`);
19
+ }
20
+ }
21
+ /** Layout produced by `npm run copy:circuits`, relative to a circuits root. */
22
+ const ARTIFACT_LAYOUT = {
23
+ transaction: {
24
+ wasm: "transaction/transaction_js/transaction.wasm",
25
+ zkey: "transaction/transaction_final.zkey",
26
+ },
27
+ swap: {
28
+ wasm: "swap/swap_js/swap.wasm",
29
+ zkey: "swap/swap_final.zkey",
30
+ },
31
+ };
32
+ /**
33
+ * Resolve circuit artifacts from disk when the caller did not supply them.
34
+ *
35
+ * Search order, first hit wins:
36
+ *
37
+ * 1. $VEILO_CIRCUITS_DIR explicit override
38
+ * 2. <package>/circuits populated by `npm run copy:circuits`
39
+ * 3. <cwd>/circuits
40
+ * 4. <cwd>/node_modules/@veilo/sdk-core/circuits
41
+ *
42
+ * NODE ONLY, AND DELIBERATELY LAZY. `node:fs` is imported inside the call, not
43
+ * at module scope: this module is reachable from the package root export, and a
44
+ * top-level `node:fs` import throws at bundle time in browser builds with no
45
+ * Node polyfill — the same reason `random.ts` avoids `node:crypto`. Browsers
46
+ * must pass `CircuitArtifacts` explicitly; there is nothing to resolve there.
47
+ *
48
+ * @throws when no candidate directory holds both files, listing what it tried
49
+ */
50
+ export async function resolveCircuitArtifacts(circuit) {
51
+ let fs;
52
+ let path;
53
+ try {
54
+ fs = await Function('return import("node:fs")')();
55
+ path = await Function('return import("node:path")')();
56
+ }
57
+ catch {
58
+ throw new Error(`Cannot resolve ${circuit} circuit artifacts: no filesystem available. ` +
59
+ "Pass CircuitArtifacts explicitly (browsers must supply buffers or URLs).");
60
+ }
61
+ const layout = ARTIFACT_LAYOUT[circuit];
62
+ if (!layout) {
63
+ throw new Error(`Unknown circuit ${JSON.stringify(circuit)}. Known circuits: ` +
64
+ `${Object.keys(ARTIFACT_LAYOUT).join(", ")}.`);
11
65
  }
66
+ const cwd = typeof process !== "undefined" ? process.cwd() : ".";
67
+ // __dirname exists in the CJS build; the ESM build falls back to cwd-relative
68
+ // candidates. dist/cjs/prover.js → ../../circuits is the package root copy.
69
+ const packageDir = typeof __dirname !== "undefined"
70
+ ? path.resolve(__dirname, "..", "..", "circuits")
71
+ : undefined;
72
+ const roots = [
73
+ process.env?.VEILO_CIRCUITS_DIR,
74
+ packageDir,
75
+ path.resolve(cwd, "circuits"),
76
+ path.resolve(cwd, "node_modules", "@veilo", "sdk-core", "circuits"),
77
+ ].filter((root) => Boolean(root));
78
+ for (const root of roots) {
79
+ const wasmPath = path.resolve(root, layout.wasm);
80
+ const zkeyPath = path.resolve(root, layout.zkey);
81
+ if (fs.existsSync(wasmPath) && fs.existsSync(zkeyPath)) {
82
+ return { wasmPath, zkeyPath };
83
+ }
84
+ }
85
+ throw new Error(`Cannot resolve ${circuit} circuit artifacts. Looked for ${layout.wasm} ` +
86
+ `and ${layout.zkey} under:\n ${roots.join("\n ")}\n` +
87
+ "Run `npm run copy:circuits` in the SDK, set VEILO_CIRCUITS_DIR, or pass " +
88
+ "CircuitArtifacts explicitly.");
12
89
  }
13
90
  /**
14
91
  * Create a proof builder function for the transaction circuit.
@@ -37,18 +114,30 @@ async function loadSnarkjs() {
37
114
  * ```
38
115
  */
39
116
  export function createTransactionProver(artifacts) {
117
+ // Resolved on first use, not at factory time: constructing a prover must stay
118
+ // free of filesystem access so browser bundles can import this module.
119
+ let resolved;
40
120
  return async (inputs) => {
41
121
  const snarkjs = await loadSnarkjs();
122
+ resolved ?? (resolved = artifacts
123
+ ? Promise.resolve(artifacts)
124
+ : resolveCircuitArtifacts("transaction"));
125
+ const { wasmPath, zkeyPath } = await resolved;
42
126
  const formattedInputs = formatInputsForSnarkjs(inputs);
43
- const { proof } = await snarkjs.groth16.fullProve(formattedInputs, artifacts.wasmPath, artifacts.zkeyPath);
127
+ const { proof } = await snarkjs.groth16.fullProve(formattedInputs, wasmPath, zkeyPath);
44
128
  return proof;
45
129
  };
46
130
  }
47
131
  /** Create a proof builder for the current `swap.circom` witness shape. */
48
132
  export function createSwapProver(artifacts) {
133
+ let resolved;
49
134
  return async (inputs) => {
50
135
  const snarkjs = await loadSnarkjs();
51
- const { proof } = await snarkjs.groth16.fullProve(formatSwapInputsForSnarkjs(inputs), artifacts.wasmPath, artifacts.zkeyPath);
136
+ resolved ?? (resolved = artifacts
137
+ ? Promise.resolve(artifacts)
138
+ : resolveCircuitArtifacts("swap"));
139
+ const { wasmPath, zkeyPath } = await resolved;
140
+ const { proof } = await snarkjs.groth16.fullProve(formatSwapInputsForSnarkjs(inputs), wasmPath, zkeyPath);
52
141
  return proof;
53
142
  };
54
143
  }
@@ -63,18 +152,20 @@ export function createSwapProver(artifacts) {
63
152
  * @returns true if the proof is valid
64
153
  */
65
154
  export async function verifyProof(proof, publicSignals, vkey) {
66
- // eslint-disable-next-line @typescript-eslint/no-var-requires
67
- let snarkjs;
68
- try {
69
- snarkjs = require("snarkjs");
70
- }
71
- catch {
72
- throw new Error('snarkjs is required for proof verification. Install it: npm install snarkjs');
73
- }
155
+ const snarkjs = await loadSnarkjs("proof verification");
74
156
  let vkeyObj;
75
157
  if (typeof vkey === "string") {
76
- // Node.js file path — read and parse
77
- const fs = await import("fs");
158
+ // Node.js file path — read and parse. Same hidden import as
159
+ // resolveCircuitArtifacts: a plain `await import("fs")` is followed by
160
+ // bundlers and breaks browser builds that have no Node polyfill.
161
+ let fs;
162
+ try {
163
+ fs = await Function('return import("node:fs")')();
164
+ }
165
+ catch {
166
+ throw new Error("Reading a verification key from a path requires Node. Pass the parsed " +
167
+ "verification key object instead.");
168
+ }
78
169
  vkeyObj = JSON.parse(fs.readFileSync(vkey, "utf-8"));
79
170
  }
80
171
  else {