@unlink-xyz/core 0.1.3-canary.fd5dddf → 0.1.4

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 (213) hide show
  1. package/README.md +9 -0
  2. package/dist/account/account.d.ts +31 -2
  3. package/dist/account/account.d.ts.map +1 -1
  4. package/dist/account/accounts.d.ts +42 -0
  5. package/dist/account/accounts.d.ts.map +1 -0
  6. package/dist/account/seed.d.ts +45 -0
  7. package/dist/account/seed.d.ts.map +1 -0
  8. package/dist/account/serialization.d.ts +6 -0
  9. package/dist/account/serialization.d.ts.map +1 -0
  10. package/dist/browser/index.js +34424 -86406
  11. package/dist/browser/index.js.map +1 -1
  12. package/dist/browser/wallet/index.js +55942 -0
  13. package/dist/browser/wallet/index.js.map +1 -0
  14. package/dist/clients/broadcaster.d.ts +1 -0
  15. package/dist/clients/broadcaster.d.ts.map +1 -1
  16. package/dist/clients/indexer.d.ts +5 -0
  17. package/dist/clients/indexer.d.ts.map +1 -1
  18. package/dist/config.d.ts +6 -4
  19. package/dist/config.d.ts.map +1 -1
  20. package/dist/core.d.ts.map +1 -1
  21. package/dist/crypto/adapters/index.d.ts +17 -0
  22. package/dist/crypto/adapters/index.d.ts.map +1 -0
  23. package/dist/crypto/adapters/polyfills.d.ts +5 -0
  24. package/dist/crypto/adapters/polyfills.d.ts.map +1 -0
  25. package/dist/crypto/encrypt.d.ts +33 -0
  26. package/dist/crypto/encrypt.d.ts.map +1 -0
  27. package/dist/crypto/secure-memory.d.ts.map +1 -0
  28. package/dist/errors.d.ts +8 -0
  29. package/dist/errors.d.ts.map +1 -1
  30. package/dist/index.d.ts +6 -2
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +6721 -23
  33. package/dist/index.js.map +1 -0
  34. package/dist/keys/derive.d.ts +2 -2
  35. package/dist/keys/derive.d.ts.map +1 -1
  36. package/dist/keys/hex.d.ts +1 -4
  37. package/dist/keys/hex.d.ts.map +1 -1
  38. package/dist/keys/mnemonic.d.ts +0 -2
  39. package/dist/keys/mnemonic.d.ts.map +1 -1
  40. package/dist/keys.d.ts +1 -0
  41. package/dist/keys.d.ts.map +1 -1
  42. package/dist/prover/config.d.ts +54 -9
  43. package/dist/prover/config.d.ts.map +1 -1
  44. package/dist/prover/integrity.d.ts +20 -0
  45. package/dist/prover/integrity.d.ts.map +1 -0
  46. package/dist/prover/prover.d.ts +16 -31
  47. package/dist/prover/prover.d.ts.map +1 -1
  48. package/dist/state/merkle/hydrator.d.ts +21 -19
  49. package/dist/state/merkle/hydrator.d.ts.map +1 -1
  50. package/dist/state/merkle/index.d.ts +1 -1
  51. package/dist/state/merkle/index.d.ts.map +1 -1
  52. package/dist/state/store/ciphertext-store.d.ts +7 -0
  53. package/dist/state/store/ciphertext-store.d.ts.map +1 -1
  54. package/dist/state/store/index.d.ts +1 -1
  55. package/dist/state/store/index.d.ts.map +1 -1
  56. package/dist/state/store/job-store.d.ts.map +1 -1
  57. package/dist/state/store/jobs.d.ts +14 -16
  58. package/dist/state/store/jobs.d.ts.map +1 -1
  59. package/dist/state/store/leaf-store.d.ts +4 -0
  60. package/dist/state/store/leaf-store.d.ts.map +1 -1
  61. package/dist/state/store/nullifier-store.d.ts.map +1 -1
  62. package/dist/state/store/records.d.ts +8 -0
  63. package/dist/state/store/records.d.ts.map +1 -1
  64. package/dist/state/store/store.d.ts +18 -0
  65. package/dist/state/store/store.d.ts.map +1 -1
  66. package/dist/storage/indexeddb.d.ts.map +1 -1
  67. package/dist/storage/memory.d.ts.map +1 -1
  68. package/dist/transactions/adapter.d.ts +31 -0
  69. package/dist/transactions/adapter.d.ts.map +1 -0
  70. package/dist/transactions/deposit.d.ts +1 -1
  71. package/dist/transactions/deposit.d.ts.map +1 -1
  72. package/dist/transactions/index.d.ts +4 -2
  73. package/dist/transactions/index.d.ts.map +1 -1
  74. package/dist/transactions/note-sync.d.ts +3 -3
  75. package/dist/transactions/note-sync.d.ts.map +1 -1
  76. package/dist/transactions/reconcile.d.ts +1 -1
  77. package/dist/transactions/reconcile.d.ts.map +1 -1
  78. package/dist/transactions/transact.d.ts +21 -2
  79. package/dist/transactions/transact.d.ts.map +1 -1
  80. package/dist/transactions/transaction-planner.d.ts +1 -1
  81. package/dist/transactions/transaction-planner.d.ts.map +1 -1
  82. package/dist/transactions/transfer-planner.d.ts +2 -1
  83. package/dist/transactions/transfer-planner.d.ts.map +1 -1
  84. package/dist/transactions/types/deposit.d.ts +3 -3
  85. package/dist/transactions/types/deposit.d.ts.map +1 -1
  86. package/dist/transactions/types/domain.d.ts +3 -0
  87. package/dist/transactions/types/domain.d.ts.map +1 -1
  88. package/dist/transactions/types/options.d.ts +14 -5
  89. package/dist/transactions/types/options.d.ts.map +1 -1
  90. package/dist/transactions/types/planning.d.ts +2 -0
  91. package/dist/transactions/types/planning.d.ts.map +1 -1
  92. package/dist/transactions/types/state-stores.d.ts +53 -5
  93. package/dist/transactions/types/state-stores.d.ts.map +1 -1
  94. package/dist/transactions/types/transact.d.ts +10 -3
  95. package/dist/transactions/types/transact.d.ts.map +1 -1
  96. package/dist/transactions/withdrawal-planner.d.ts +1 -1
  97. package/dist/transactions/withdrawal-planner.d.ts.map +1 -1
  98. package/dist/tsconfig.tsbuildinfo +1 -1
  99. package/dist/tsup.config.d.ts +8 -0
  100. package/dist/tsup.config.d.ts.map +1 -0
  101. package/dist/types.d.ts +1 -0
  102. package/dist/types.d.ts.map +1 -1
  103. package/dist/utils/amounts.d.ts +0 -13
  104. package/dist/utils/amounts.d.ts.map +1 -1
  105. package/dist/utils/async.js +37 -34
  106. package/dist/utils/async.js.map +1 -0
  107. package/dist/utils/bigint.d.ts +0 -2
  108. package/dist/utils/bigint.d.ts.map +1 -1
  109. package/dist/utils/random.d.ts +5 -0
  110. package/dist/utils/random.d.ts.map +1 -1
  111. package/dist/utils/validators.d.ts.map +1 -1
  112. package/dist/vitest.config.d.ts.map +1 -1
  113. package/dist/wallet/adapter.d.ts +21 -0
  114. package/dist/wallet/adapter.d.ts.map +1 -0
  115. package/dist/wallet/burner/service.d.ts +32 -0
  116. package/dist/wallet/burner/service.d.ts.map +1 -0
  117. package/dist/wallet/burner/types.d.ts +47 -0
  118. package/dist/wallet/burner/types.d.ts.map +1 -0
  119. package/dist/wallet/index.d.ts +20 -0
  120. package/dist/wallet/index.d.ts.map +1 -0
  121. package/dist/wallet/index.js +6462 -0
  122. package/dist/wallet/index.js.map +1 -0
  123. package/dist/wallet/sdk.d.ts +48 -0
  124. package/dist/wallet/sdk.d.ts.map +1 -0
  125. package/dist/wallet/types.d.ts +457 -0
  126. package/dist/wallet/types.d.ts.map +1 -0
  127. package/dist/wallet/unlink-wallet.d.ts +187 -0
  128. package/dist/wallet/unlink-wallet.d.ts.map +1 -0
  129. package/package.json +16 -6
  130. package/dist/account/account.js +0 -142
  131. package/dist/circuits.json +0 -74
  132. package/dist/clients/broadcaster.js +0 -30
  133. package/dist/clients/http.js +0 -72
  134. package/dist/clients/indexer.js +0 -94
  135. package/dist/config.js +0 -36
  136. package/dist/constants.js +0 -5
  137. package/dist/core.js +0 -15
  138. package/dist/crypto-adapters/auto-init.d.ts +0 -2
  139. package/dist/crypto-adapters/auto-init.d.ts.map +0 -1
  140. package/dist/crypto-adapters/auto-init.js +0 -7
  141. package/dist/crypto-adapters/index.d.ts +0 -22
  142. package/dist/crypto-adapters/index.d.ts.map +0 -1
  143. package/dist/crypto-adapters/index.js +0 -47
  144. package/dist/crypto-adapters/polyfills.d.ts +0 -5
  145. package/dist/crypto-adapters/polyfills.d.ts.map +0 -1
  146. package/dist/crypto-adapters/polyfills.js +0 -8
  147. package/dist/errors.js +0 -36
  148. package/dist/history/index.js +0 -2
  149. package/dist/history/service.js +0 -354
  150. package/dist/history/types.js +0 -1
  151. package/dist/keys/address.js +0 -55
  152. package/dist/keys/derive.js +0 -112
  153. package/dist/keys/hex.js +0 -66
  154. package/dist/keys/index.js +0 -4
  155. package/dist/keys/mnemonic.js +0 -23
  156. package/dist/keys.js +0 -45
  157. package/dist/prover/config.js +0 -70
  158. package/dist/prover/index.js +0 -1
  159. package/dist/prover/prover.js +0 -291
  160. package/dist/prover/registry.js +0 -18
  161. package/dist/schema.js +0 -14
  162. package/dist/state/index.js +0 -2
  163. package/dist/state/merkle/hydrator.js +0 -37
  164. package/dist/state/merkle/index.js +0 -2
  165. package/dist/state/merkle/merkle-tree.js +0 -113
  166. package/dist/state/store/ciphertext-store.js +0 -37
  167. package/dist/state/store/history-store.js +0 -53
  168. package/dist/state/store/index.js +0 -9
  169. package/dist/state/store/job-store.js +0 -144
  170. package/dist/state/store/jobs.js +0 -1
  171. package/dist/state/store/leaf-store.js +0 -32
  172. package/dist/state/store/note-store.js +0 -146
  173. package/dist/state/store/nullifier-store.js +0 -60
  174. package/dist/state/store/records.js +0 -1
  175. package/dist/state/store/root-store.js +0 -26
  176. package/dist/state/store/store.js +0 -113
  177. package/dist/storage/index.js +0 -2
  178. package/dist/storage/indexeddb.js +0 -205
  179. package/dist/storage/memory.js +0 -91
  180. package/dist/transactions/deposit.js +0 -220
  181. package/dist/transactions/index.js +0 -9
  182. package/dist/transactions/note-selection.js +0 -201
  183. package/dist/transactions/note-sync.js +0 -485
  184. package/dist/transactions/reconcile.js +0 -85
  185. package/dist/transactions/transact.js +0 -450
  186. package/dist/transactions/transaction-planner.js +0 -116
  187. package/dist/transactions/transfer-planner.js +0 -85
  188. package/dist/transactions/types/deposit.js +0 -1
  189. package/dist/transactions/types/domain.js +0 -4
  190. package/dist/transactions/types/index.js +0 -17
  191. package/dist/transactions/types/options.js +0 -1
  192. package/dist/transactions/types/planning.js +0 -1
  193. package/dist/transactions/types/state-stores.js +0 -1
  194. package/dist/transactions/types/transact.js +0 -1
  195. package/dist/transactions/withdrawal-planner.js +0 -128
  196. package/dist/tsup.browser.config.js +0 -34
  197. package/dist/types.js +0 -1
  198. package/dist/utils/amounts.js +0 -89
  199. package/dist/utils/bigint.js +0 -29
  200. package/dist/utils/crypto.d.ts +0 -18
  201. package/dist/utils/crypto.d.ts.map +0 -1
  202. package/dist/utils/crypto.js +0 -45
  203. package/dist/utils/format.js +0 -33
  204. package/dist/utils/json-codec.js +0 -25
  205. package/dist/utils/notes.js +0 -14
  206. package/dist/utils/polling.js +0 -11
  207. package/dist/utils/random.js +0 -27
  208. package/dist/utils/secure-memory.d.ts.map +0 -1
  209. package/dist/utils/secure-memory.js +0 -28
  210. package/dist/utils/signature.js +0 -14
  211. package/dist/utils/validators.js +0 -96
  212. package/dist/vitest.config.js +0 -13
  213. /package/dist/{utils → crypto}/secure-memory.d.ts +0 -0
@@ -1,85 +0,0 @@
1
- import { ValidationError } from "../errors.js";
2
- import { planTransaction } from "./transaction-planner.js";
3
- /**
4
- * Plan transfer transaction(s).
5
- * Accepts 1 or more transfers. When multiple transfers use the same token,
6
- * notes are tracked across transfers to avoid double-spending.
7
- *
8
- * @param notes - Available unspent notes (all tokens)
9
- * @param transfers - Transfers to plan (each with token, amount, recipientMpk)
10
- * @param senderMpk - Sender's master public key (for change outputs)
11
- * @returns Array of transaction plans, one per transfer input
12
- *
13
- * @example
14
- * ```typescript
15
- * // Single transfer
16
- * const [plan] = planTransfers(notes, [{ token, amount: 100n, recipientMpk }], senderMpk);
17
- *
18
- * // Multiple transfers (possibly same token)
19
- * const plans = planTransfers(notes, [
20
- * { token: ETH, amount: 100n, recipientMpk: recipient1Mpk },
21
- * { token: USDC, amount: 50n, recipientMpk: recipient2Mpk },
22
- * ], senderMpk);
23
- * ```
24
- */
25
- export function planTransfers(notes, transfers, senderMpk) {
26
- if (!transfers.length) {
27
- throw new ValidationError("At least one transfer is required");
28
- }
29
- // Validate all transfers upfront
30
- for (const t of transfers) {
31
- if (!t.token) {
32
- throw new ValidationError(`Missing token address in transfer: ${JSON.stringify(t)}`);
33
- }
34
- // Convert amount to bigint if needed (handles string amounts from frontend)
35
- const amount = typeof t.amount === "bigint" ? t.amount : BigInt(t.amount);
36
- if (amount <= 0n) {
37
- throw new ValidationError(`Invalid transfer amount for ${t.token}: ${t.amount}`);
38
- }
39
- // Update amount to bigint for downstream use
40
- t.amount = amount;
41
- }
42
- // Pre-validate total balances per token (use normalized tokens for comparison)
43
- const requiredByToken = new Map();
44
- for (const t of transfers) {
45
- const tokenLower = t.token.toLowerCase();
46
- const existing = requiredByToken.get(tokenLower) ?? 0n;
47
- requiredByToken.set(tokenLower, existing + t.amount);
48
- }
49
- for (const [tokenLower, required] of requiredByToken) {
50
- const available = notes
51
- .filter((n) => {
52
- const noteToken = n.token;
53
- return noteToken && noteToken.toLowerCase() === tokenLower;
54
- })
55
- .reduce((sum, n) => sum + BigInt(n.value), 0n);
56
- if (available < required) {
57
- throw new ValidationError(`Insufficient balance for ${tokenLower}: need ${required}, have ${available}`);
58
- }
59
- }
60
- // Track used note indices per token to avoid double-spending
61
- const usedNotesByToken = new Map();
62
- const plans = [];
63
- for (const t of transfers) {
64
- const tokenLower = t.token.toLowerCase();
65
- // Get available notes for this token, excluding already-used ones
66
- const usedIndices = usedNotesByToken.get(tokenLower) ?? new Set();
67
- const availableNotes = notes.filter((n) => {
68
- const noteToken = n.token;
69
- return (noteToken &&
70
- noteToken.toLowerCase() === tokenLower &&
71
- !usedIndices.has(n.index));
72
- });
73
- // Plan this transfer using the existing planTransaction function
74
- const plan = planTransaction(availableNotes, [{ mpk: t.recipientMpk, amount: t.amount }], senderMpk, t.token);
75
- // Mark selected notes as used
76
- if (!usedNotesByToken.has(tokenLower)) {
77
- usedNotesByToken.set(tokenLower, new Set());
78
- }
79
- for (const input of plan.inputs) {
80
- usedNotesByToken.get(tokenLower).add(input.index);
81
- }
82
- plans.push(plan);
83
- }
84
- return plans;
85
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,4 +0,0 @@
1
- /**
2
- * Core domain types for cryptographic operations.
3
- */
4
- export {};
@@ -1,17 +0,0 @@
1
- /**
2
- * Transaction type definitions.
3
- *
4
- * Organized by concern:
5
- * - state-stores: Database/storage interfaces
6
- * - options: Configuration for services
7
- * - domain: Core cryptographic types
8
- * - deposit: Deposit-specific types
9
- * - transact: Transaction-specific types
10
- * - planning: Transaction planning types
11
- */
12
- export * from "./state-stores.js";
13
- export * from "./options.js";
14
- export * from "./domain.js";
15
- export * from "./deposit.js";
16
- export * from "./transact.js";
17
- export * from "./planning.js";
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1,128 +0,0 @@
1
- import { ProofError, ValidationError } from "../errors.js";
2
- import { CIRCUIT_REGISTRY } from "../prover/registry.js";
3
- import { randomBigint } from "../utils/random.js";
4
- import { selectNotesForAmount } from "./note-selection.js";
5
- /**
6
- * Select the smallest circuit that fits the given input/output counts.
7
- * For withdrawals, outputs = change only (0 or 1).
8
- */
9
- function selectCircuitForWithdrawal(inputCount, outputCount) {
10
- // Sort circuits by total size (inputs + outputs) ascending
11
- const circuits = Object.values(CIRCUIT_REGISTRY).sort((a, b) => a.inputs + a.outputs - (b.inputs + b.outputs));
12
- const circuit = circuits.find((c) => c.inputs >= inputCount && c.outputs >= outputCount);
13
- if (!circuit) {
14
- throw new ProofError(`No circuit supports ${inputCount} inputs and ${outputCount} outputs. ` +
15
- `Available: ${circuits.map((c) => `${c.inputs}x${c.outputs}`).join(", ")}`);
16
- }
17
- return circuit;
18
- }
19
- /**
20
- * Plan a single withdrawal transaction. Used internally by `planWithdrawals`.
21
- */
22
- function planSingleWithdrawal(notes, withdrawAmount, recipientAddress, senderMpk, token) {
23
- if (withdrawAmount <= 0n) {
24
- throw new ValidationError("Withdrawal amount must be positive");
25
- }
26
- const selection = selectNotesForAmount(notes, withdrawAmount, {
27
- recipientCount: 0,
28
- });
29
- const { selected: inputs, totalInput, change } = selection;
30
- const changeOutputCount = change > 0n ? 1 : 0;
31
- const outputCount = changeOutputCount + 1;
32
- const circuit = selectCircuitForWithdrawal(inputs.length, outputCount);
33
- const outputNotes = [];
34
- if (change > 0n) {
35
- const random = randomBigint();
36
- outputNotes.push({
37
- mpk: senderMpk,
38
- random,
39
- token,
40
- amount: change,
41
- });
42
- }
43
- const withdrawal = {
44
- npk: BigInt(recipientAddress),
45
- amount: withdrawAmount,
46
- token,
47
- };
48
- return {
49
- inputs,
50
- outputNotes,
51
- withdrawal,
52
- circuit,
53
- totalInput,
54
- withdrawAmount,
55
- change,
56
- token,
57
- };
58
- }
59
- /**
60
- * Plan withdrawal transaction(s).
61
- * Accepts 1 or more withdrawals. When multiple withdrawals use the same token,
62
- * notes are tracked across withdrawals to avoid double-spending.
63
- *
64
- * @param notes - Available unspent notes (all tokens)
65
- * @param withdrawals - Withdrawals to plan (each with token, amount, recipient)
66
- * @param senderMpk - Sender's master public key (for change outputs)
67
- * @returns Array of withdrawal plans, one per withdrawal input
68
- *
69
- * @example
70
- * ```typescript
71
- * // Single withdrawal
72
- * const [plan] = planWithdrawals(notes, [{ token, amount: 100n, recipient: "0x..." }], mpk);
73
- *
74
- * // Multiple withdrawals (possibly same token)
75
- * const plans = planWithdrawals(notes, [
76
- * { token: ETH, amount: 100n, recipient: "0x..." },
77
- * { token: USDC, amount: 50n, recipient: "0x..." },
78
- * ], mpk);
79
- * ```
80
- */
81
- export function planWithdrawals(notes, withdrawals, senderMpk) {
82
- if (!withdrawals.length) {
83
- throw new ValidationError("At least one withdrawal is required");
84
- }
85
- // Validate all withdrawals upfront
86
- for (const w of withdrawals) {
87
- if (w.amount <= 0n) {
88
- throw new ValidationError(`Invalid withdrawal amount for ${w.token}: ${w.amount}`);
89
- }
90
- }
91
- // Pre-validate total balances per token (use normalized tokens for comparison)
92
- const requiredByToken = new Map();
93
- for (const w of withdrawals) {
94
- const tokenLower = w.token.toLowerCase();
95
- const existing = requiredByToken.get(tokenLower) ?? 0n;
96
- requiredByToken.set(tokenLower, existing + w.amount);
97
- }
98
- for (const [tokenLower, required] of requiredByToken) {
99
- const available = notes
100
- .filter((n) => n.token.toLowerCase() ===
101
- tokenLower)
102
- .reduce((sum, n) => sum + BigInt(n.value), 0n);
103
- if (available < required) {
104
- throw new ValidationError(`Insufficient balance for ${tokenLower}: need ${required}, have ${available}`);
105
- }
106
- }
107
- // Track used note indices per token to avoid double-spending
108
- const usedNotesByToken = new Map();
109
- const plans = [];
110
- for (const w of withdrawals) {
111
- const tokenLower = w.token.toLowerCase();
112
- // Get available notes for this token, excluding already-used ones
113
- const usedIndices = usedNotesByToken.get(tokenLower) ?? new Set();
114
- const availableNotes = notes.filter((n) => n.token.toLowerCase() ===
115
- tokenLower && !usedIndices.has(n.index));
116
- // Plan this withdrawal (pass original token for output)
117
- const plan = planSingleWithdrawal(availableNotes, w.amount, w.recipient, senderMpk, w.token);
118
- // Mark selected notes as used
119
- if (!usedNotesByToken.has(tokenLower)) {
120
- usedNotesByToken.set(tokenLower, new Set());
121
- }
122
- for (const input of plan.inputs) {
123
- usedNotesByToken.get(tokenLower).add(input.index);
124
- }
125
- plans.push(plan);
126
- }
127
- return plans;
128
- }
@@ -1,34 +0,0 @@
1
- import { NodeGlobalsPolyfillPlugin } from "@esbuild-plugins/node-globals-polyfill";
2
- import { NodeModulesPolyfillPlugin } from "@esbuild-plugins/node-modules-polyfill";
3
- import { defineConfig } from "tsup";
4
- /**
5
- * Browser build configuration.
6
- * Bundles all dependencies with Node.js polyfills for browser compatibility.
7
- */
8
- export default defineConfig({
9
- entry: ["index.ts"],
10
- format: ["esm"],
11
- dts: false, // Types are generated by the main tsc build
12
- clean: false, // Don't clean dist/ to preserve tsc output
13
- splitting: false,
14
- sourcemap: true,
15
- minify: false,
16
- // Bundle everything including dependencies for browser compatibility
17
- noExternal: [/.*/],
18
- esbuildPlugins: [
19
- NodeModulesPolyfillPlugin(),
20
- NodeGlobalsPolyfillPlugin({
21
- buffer: true,
22
- process: true,
23
- }),
24
- ],
25
- esbuildOptions(options) {
26
- options.supported = {
27
- ...options.supported,
28
- "top-level-await": true,
29
- };
30
- },
31
- platform: "browser",
32
- target: "es2022",
33
- outDir: "dist/browser",
34
- });
package/dist/types.js DELETED
@@ -1 +0,0 @@
1
- export {};
@@ -1,89 +0,0 @@
1
- import { ValidationError } from "../errors.js";
2
- /**
3
- * Parse a decimal string to bigint with specified decimals.
4
- *
5
- * @param value - Decimal string (e.g., "10.5", "42")
6
- * @param decimals - Number of decimal
7
- * @returns Amount as bigint in atomic units
8
- * @throws ValidationError if value is invalid or has too many decimal places
9
- *
10
- * @example
11
- * parseAmount("10.5", 18) // Returns 10500000000000000000n
12
- * parseAmount("0.001", 6) // Returns 1000n
13
- */
14
- export function parseAmount(value, decimals) {
15
- const trimmed = value.trim();
16
- if (!trimmed) {
17
- throw new ValidationError("Amount cannot be empty");
18
- }
19
- if (!/^\d*(\.\d*)?$/.test(trimmed)) {
20
- throw new ValidationError("Amount must be numeric and can include decimals (e.g., '10.5')");
21
- }
22
- const [rawWhole = "0", rawFraction = ""] = trimmed.split(".");
23
- const whole = rawWhole === "" ? "0" : rawWhole;
24
- if (rawFraction.length > decimals) {
25
- throw new ValidationError(`Amount supports up to ${decimals} decimal places; trim the fractional part`);
26
- }
27
- // Pad fraction to full decimal places
28
- const fraction = rawFraction.padEnd(decimals, "0");
29
- const combined = `${whole}${fraction}`;
30
- // Remove leading zeros
31
- const normalized = combined.replace(/^0+(?=\d)/, "");
32
- return normalized ? BigInt(normalized) : 0n;
33
- }
34
- /**
35
- * Format a bigint amount to a decimal string.
36
- *
37
- * @param amount - Amount in atomic units as bigint
38
- * @param decimals - Number of decimal places
39
- * @returns Human-readable decimal string
40
- *
41
- * @example
42
- * formatAmount(10500000000000000000n, 18) // Returns "10.5"
43
- * formatAmount(1000n, 6) // Returns "0.001"
44
- */
45
- export function formatAmount(amount, decimals) {
46
- if (amount < 0n) {
47
- throw new ValidationError("Amount must be non-negative");
48
- }
49
- const amountStr = amount.toString().padStart(decimals + 1, "0");
50
- const wholePartEnd = amountStr.length - decimals;
51
- const wholePart = amountStr.slice(0, wholePartEnd) || "0";
52
- const fractionPart = amountStr.slice(wholePartEnd);
53
- // Remove trailing zeros from fraction
54
- const trimmedFraction = fractionPart.replace(/0+$/, "");
55
- return trimmedFraction ? `${wholePart}.${trimmedFraction}` : wholePart;
56
- }
57
- /**
58
- * Split a total amount into N equal parts, distributing remainder evenly.
59
- *
60
- * @param total - Total amount to split
61
- * @param parts - Number of parts to split into
62
- * @returns Array of amounts that sum to total
63
- * @throws ValidationError if parts is invalid or amount is too small to split
64
- *
65
- * @example
66
- * splitAmount(100n, 3) // Returns [34n, 33n, 33n] (remainder goes to first outputs)
67
- * splitAmount(10n, 2) // Returns [5n, 5n]
68
- */
69
- export function splitAmount(total, parts) {
70
- if (parts === 0) {
71
- return [];
72
- }
73
- if (parts < 0) {
74
- throw new ValidationError("Number of parts must be non-negative");
75
- }
76
- if (!Number.isInteger(parts)) {
77
- throw new ValidationError("Number of parts must be an integer");
78
- }
79
- if (total < BigInt(parts)) {
80
- throw new ValidationError(`Amount (${total}) is too small to distribute across ${parts} outputs (minimum 1 per output)`);
81
- }
82
- const base = total / BigInt(parts);
83
- if (base <= 0n) {
84
- throw new ValidationError("Output share must be positive");
85
- }
86
- const remainder = Number(total - base * BigInt(parts));
87
- // Distribute remainder across first N outputs
88
- return Array.from({ length: parts }, (_, idx) => base + (idx < remainder ? 1n : 0n));
89
- }
@@ -1,29 +0,0 @@
1
- import { ValidationError } from "../errors.js";
2
- import { FieldSize, Hex } from "../keys/hex.js";
3
- /**
4
- * BigInt helpers shared across transaction builders to keep formatting consistent.
5
- */
6
- export function formatUint256(value) {
7
- assertNonNegative("uint256", value);
8
- return Hex.fromBigInt(value, FieldSize.SCALAR, true);
9
- }
10
- export function parseHexToBigInt(value) {
11
- return Hex.toBigInt(value);
12
- }
13
- export function parseNumToBigInt(value) {
14
- if (value === undefined) {
15
- throw new ValidationError("Value is undefined");
16
- }
17
- return BigInt(value);
18
- }
19
- export function assertNonNegative(label, value) {
20
- if (value < 0n) {
21
- throw new ValidationError(`${label} must be non-negative`);
22
- }
23
- }
24
- export function ensureBigint(label, value) {
25
- if (typeof value !== "bigint") {
26
- throw new ValidationError(`${label} must be provided as a bigint`);
27
- }
28
- return value;
29
- }
@@ -1,18 +0,0 @@
1
- import { Ciphertext, NoteInput } from "../transactions/types/index.js";
2
- export declare function encryptNote(note: NoteInput): Ciphertext;
3
- export declare function encrypt(data: bigint, key: bigint): bigint;
4
- export declare function decryptNote(c: Ciphertext, key: bigint): NoteInput;
5
- export declare function deriveCommitment(note: {
6
- npk: bigint;
7
- amount: bigint;
8
- token: string;
9
- }): bigint;
10
- /**
11
- * Derive the nullifier public key (npk) from a note.
12
- */
13
- export declare function deriveNpk(note: NoteInput): bigint;
14
- /**
15
- * Compute the commitment for a note given its npk.
16
- */
17
- export declare function computeCommitment(note: NoteInput, npk: bigint): bigint;
18
- //# sourceMappingURL=crypto.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../utils/crypto.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAGvE,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,UAAU,CAQvD;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,CAYjE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,UAGA;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,UAExC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,UAG7D"}
@@ -1,45 +0,0 @@
1
- import { poseidon } from "../crypto-adapters/index.js";
2
- import { CoreError } from "../errors.js";
3
- import { parseHexToBigInt } from "./bigint.js";
4
- export function encryptNote(note) {
5
- return {
6
- data: [
7
- encrypt(note.random, note.mpk),
8
- encrypt(parseHexToBigInt(note.token), note.mpk),
9
- encrypt(note.amount, note.mpk),
10
- ],
11
- };
12
- }
13
- export function encrypt(data, key) {
14
- return poseidon([0x556e6c696e6b, key]) ^ data;
15
- }
16
- export function decryptNote(c, key) {
17
- const token_bigint = encrypt(c.data[1], key);
18
- if (token_bigint > 0xffffffffffffffffffffffffffffffffffffffffn) {
19
- throw new CoreError("Invalid Decrypt");
20
- }
21
- const result = {
22
- mpk: key,
23
- random: encrypt(c.data[0], key),
24
- token: "0x" + token_bigint.toString(16).padStart(40, "0"),
25
- amount: encrypt(c.data[2], key),
26
- };
27
- return result;
28
- }
29
- export function deriveCommitment(note) {
30
- const tokenScalar = BigInt(note.token);
31
- return poseidon([note.npk, tokenScalar, note.amount]);
32
- }
33
- /**
34
- * Derive the nullifier public key (npk) from a note.
35
- */
36
- export function deriveNpk(note) {
37
- return poseidon([note.mpk, note.random]);
38
- }
39
- /**
40
- * Compute the commitment for a note given its npk.
41
- */
42
- export function computeCommitment(note, npk) {
43
- const tokenScalar = BigInt(note.token);
44
- return poseidon([npk, tokenScalar, note.amount]);
45
- }
@@ -1,33 +0,0 @@
1
- import { ensureAddress } from "./validators.js";
2
- /**
3
- * Normalize and validate an Ethereum address.
4
- *
5
- * @param value - Address string to normalize
6
- * @returns Normalized lowercase address
7
- * @throws CoreError if the address is invalid
8
- *
9
- * @example
10
- * normalizeAddress("0xABC123...") // Returns "0xabc123..."
11
- */
12
- export function normalizeAddress(value) {
13
- return ensureAddress("address", value);
14
- }
15
- /**
16
- * Shorten a hex string for display.
17
- *
18
- * @param value - Hex string to shorten
19
- * @param chars - Number of characters to show at start/end (default: 4)
20
- * @returns Shortened string like "0x1234…abcd"
21
- *
22
- * @example
23
- * shortenHex("0x1234567890abcdef1234567890abcdef12345678") // "0x1234…5678"
24
- * shortenHex("0x1234567890abcdef1234567890abcdef12345678", 6) // "0x123456…345678"
25
- */
26
- export function shortenHex(value, chars = 4) {
27
- if (!value.startsWith("0x") || value.length <= chars * 2 + 2) {
28
- return value;
29
- }
30
- return `${value.slice(0, chars + 2)}…${value.slice(-chars)}`;
31
- }
32
- // Re-export random utilities from dedicated module
33
- export { randomHex, randomBigint } from "./random.js";
@@ -1,25 +0,0 @@
1
- import { CoreError } from "../errors.js";
2
- import { validateKey } from "../keys.js";
3
- const encoder = new TextEncoder();
4
- const decoder = new TextDecoder();
5
- export function encodeJson(value) {
6
- return encoder.encode(JSON.stringify(value));
7
- }
8
- export function decodeJson(payload) {
9
- try {
10
- return JSON.parse(decoder.decode(payload));
11
- }
12
- catch {
13
- throw new CoreError("failed to decode stored state payload");
14
- }
15
- }
16
- export async function putJson(storage, key, record) {
17
- validateKey(key);
18
- await storage.put(key, encodeJson(record));
19
- }
20
- export async function getJson(storage, key) {
21
- const payload = await storage.get(key);
22
- if (!payload)
23
- return null;
24
- return decodeJson(payload);
25
- }
@@ -1,14 +0,0 @@
1
- /**
2
- * Computes token balances from a list of notes.
3
- *
4
- * @param notes - Array of notes to compute balances from
5
- * @returns Record mapping token address to total balance
6
- */
7
- export function computeBalances(notes) {
8
- const totals = {};
9
- for (const note of notes) {
10
- const value = typeof note.value === "bigint" ? note.value : BigInt(note.value);
11
- totals[note.token] = (totals[note.token] ?? 0n) + value;
12
- }
13
- return totals;
14
- }
@@ -1,11 +0,0 @@
1
- /**
2
- * Shared polling configuration constants.
3
- */
4
- export const DEFAULT_POLL_INTERVAL_MS = 500;
5
- export const DEFAULT_POLL_TIMEOUT_MS = 30_000;
6
- export const MAX_POLL_INTERVAL_MS = 5_000;
7
- /**
8
- * Initial delay before first poll for fresh deposits.
9
- * Reduces wasted 404 requests while commitment is being indexed.
10
- */
11
- export const DEFAULT_INITIAL_POLL_DELAY_MS = 2_000;
@@ -1,27 +0,0 @@
1
- import { CoreError } from "../errors.js";
2
- /**
3
- * Generate a cryptographically secure random bigint.
4
- * @param bytes - Number of bytes of randomness (default: 32 for 256-bit)
5
- * @returns Random bigint
6
- */
7
- export function randomBigint(bytes = 32) {
8
- if (typeof globalThis.crypto?.getRandomValues !== "function") {
9
- throw new CoreError("crypto.getRandomValues is not available");
10
- }
11
- const buffer = new Uint8Array(bytes);
12
- globalThis.crypto.getRandomValues(buffer);
13
- return BigInt("0x" +
14
- Array.from(buffer)
15
- .map((b) => b.toString(16).padStart(2, "0"))
16
- .join(""));
17
- }
18
- /**
19
- * Generate a cryptographically secure random hex string.
20
- * @param bytes - Number of bytes of randomness
21
- * @returns Random hex string with 0x prefix
22
- */
23
- export function randomHex(bytes) {
24
- return `0x${randomBigint(bytes)
25
- .toString(16)
26
- .padStart(bytes * 2, "0")}`;
27
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"secure-memory.d.ts","sourceRoot":"","sources":["../../utils/secure-memory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAI/C"}
@@ -1,28 +0,0 @@
1
- /**
2
- * IMPORTANT limitations:
3
- * - Garbage collection timing is unpredictable
4
- * - Strings are immutable
5
- * - No compiler enforcement to prevent copies
6
- */
7
- /**
8
- * Securely zeros out a Uint8Array's contents by overwriting with zeros.
9
- * This should be called on all sensitive cryptographic material after use
10
- *
11
- * @param bytes - The Uint8Array to zeroize (will be mutated in place)
12
- *
13
- * @example
14
- * ```typescript
15
- * const privateKey = derivePrivateKey(seed);
16
- * try {
17
- * const signature = sign(message, privateKey);
18
- * return signature;
19
- * } finally {
20
- * zeroize(privateKey); // Clear sensitive data
21
- * }
22
- * ```
23
- */
24
- export function zeroize(bytes) {
25
- if (!bytes || bytes.length === 0)
26
- return;
27
- bytes.fill(0);
28
- }
@@ -1,14 +0,0 @@
1
- import { signMessage } from "../crypto-adapters/index.js";
2
- /**
3
- * Generates an EdDSA signature over a poseidon-hashed message using the spending private key.
4
- * Used for transact public signal signing.
5
- *
6
- * The spendingPrivateKey parameter should be zeroized by the caller after use.
7
- *
8
- * @param spendingPrivateKey - The 32-byte spending private key (will not be mutated)
9
- * @param message - The bigint message to sign
10
- * @returns The EdDSA signature
11
- */
12
- export function signTransactMessage(spendingPrivateKey, message) {
13
- return signMessage(spendingPrivateKey, message);
14
- }