@permissionless-technologies/upp-sdk 0.4.13 → 0.4.14

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 (53) hide show
  1. package/dist/{chunk-O6ALW7DB.js → chunk-5WLAZA3M.js} +3 -3
  2. package/dist/{chunk-O6ALW7DB.js.map → chunk-5WLAZA3M.js.map} +1 -1
  3. package/dist/{chunk-4MWEJDTR.cjs → chunk-7Y6O4P2P.cjs} +3 -3
  4. package/dist/{chunk-4MWEJDTR.cjs.map → chunk-7Y6O4P2P.cjs.map} +1 -1
  5. package/dist/{chunk-KZ7PY2PR.cjs → chunk-CTBLNYYB.cjs} +2 -2
  6. package/dist/{chunk-KZ7PY2PR.cjs.map → chunk-CTBLNYYB.cjs.map} +1 -1
  7. package/dist/{chunk-23B5XSS4.cjs → chunk-CZLMCMYE.cjs} +90 -2
  8. package/dist/chunk-CZLMCMYE.cjs.map +1 -0
  9. package/dist/{chunk-3I6ERQO3.js → chunk-GQ6JMNJI.js} +3 -3
  10. package/dist/{chunk-3I6ERQO3.js.map → chunk-GQ6JMNJI.js.map} +1 -1
  11. package/dist/{chunk-RNUG3EFC.js → chunk-NIGEAKQP.js} +89 -3
  12. package/dist/chunk-NIGEAKQP.js.map +1 -0
  13. package/dist/{chunk-5BLMSTFQ.cjs → chunk-TBGDQM33.cjs} +4 -4
  14. package/dist/{chunk-5BLMSTFQ.cjs.map → chunk-TBGDQM33.cjs.map} +1 -1
  15. package/dist/{chunk-DUBWGEB5.js → chunk-YMZM2ABJ.js} +2 -2
  16. package/dist/{chunk-DUBWGEB5.js.map → chunk-YMZM2ABJ.js.map} +1 -1
  17. package/dist/core/index.cjs +100 -92
  18. package/dist/core/index.d.cts +2 -2
  19. package/dist/core/index.d.ts +2 -2
  20. package/dist/core/index.js +4 -4
  21. package/dist/core/proof-worker-entry.cjs +60 -0
  22. package/dist/core/proof-worker-entry.cjs.map +1 -0
  23. package/dist/core/proof-worker-entry.d.cts +2 -0
  24. package/dist/core/proof-worker-entry.d.ts +2 -0
  25. package/dist/core/proof-worker-entry.js +58 -0
  26. package/dist/core/proof-worker-entry.js.map +1 -0
  27. package/dist/{index-CKCDqv2e.d.cts → index-DKFupAA8.d.cts} +8 -3
  28. package/dist/{index-DLczKlnM.d.ts → index-M91G-og3.d.ts} +8 -3
  29. package/dist/{index--eNkOLiP.d.ts → index-S2fzWmLW.d.ts} +1 -1
  30. package/dist/{index-CRaFsQD3.d.cts → index-qTwnREeK.d.cts} +1 -1
  31. package/dist/index.cjs +108 -100
  32. package/dist/index.d.cts +3 -3
  33. package/dist/index.d.ts +3 -3
  34. package/dist/index.js +5 -5
  35. package/dist/indexer/index.cjs +6 -6
  36. package/dist/indexer/index.d.cts +5 -5
  37. package/dist/indexer/index.d.ts +5 -5
  38. package/dist/indexer/index.js +1 -1
  39. package/dist/react/index.cjs +69 -21
  40. package/dist/react/index.cjs.map +1 -1
  41. package/dist/react/index.d.cts +20 -3
  42. package/dist/react/index.d.ts +20 -3
  43. package/dist/react/index.js +52 -12
  44. package/dist/react/index.js.map +1 -1
  45. package/dist/{transfer-CwwsNdGL.d.cts → transfer-BDYID3Hn.d.cts} +75 -1
  46. package/dist/{transfer-Crvdq4VN.d.ts → transfer-DLukr6ed.d.ts} +75 -1
  47. package/dist/{transfer-LGR44CER.js → transfer-LT2VGGPZ.js} +4 -4
  48. package/dist/{transfer-LGR44CER.js.map → transfer-LT2VGGPZ.js.map} +1 -1
  49. package/dist/{transfer-UZBU47HC.cjs → transfer-OPGKWWX2.cjs} +10 -10
  50. package/dist/{transfer-UZBU47HC.cjs.map → transfer-OPGKWWX2.cjs.map} +1 -1
  51. package/package.json +5 -1
  52. package/dist/chunk-23B5XSS4.cjs.map +0 -1
  53. package/dist/chunk-RNUG3EFC.js.map +0 -1
@@ -585,6 +585,80 @@ declare function formatProofForContract(proof: Proof): {
585
585
  c: [bigint, bigint];
586
586
  };
587
587
 
588
+ /**
589
+ * Proof Worker Manager — off-main-thread PLONK proof generation.
590
+ *
591
+ * Manages a Web Worker that runs snarkjs proof generation, keeping the
592
+ * main thread (and UI) responsive during the 10-30s proving time.
593
+ *
594
+ * @example
595
+ * ```ts
596
+ * // Create worker (consumer handles bundler integration)
597
+ * const worker = new Worker(
598
+ * new URL('@permissionless-technologies/upp-sdk/worker', import.meta.url)
599
+ * )
600
+ * const manager = new ProofWorkerManager(worker)
601
+ *
602
+ * const result = await manager.prove('transfer', circuitInputs, '/circuits/',
603
+ * (stage, msg) => console.log(stage, msg)
604
+ * )
605
+ *
606
+ * // Cleanup
607
+ * manager.terminate()
608
+ * ```
609
+ */
610
+
611
+ interface ProofWorkerRequest {
612
+ type: 'prove';
613
+ id: string;
614
+ circuitType: string;
615
+ inputs: Record<string, any>;
616
+ baseUrl: string;
617
+ }
618
+ type ProofWorkerResponse = {
619
+ type: 'progress';
620
+ id: string;
621
+ stage: PlonkProvingStage;
622
+ message: string;
623
+ } | {
624
+ type: 'result';
625
+ id: string;
626
+ proof: ProofResult;
627
+ } | {
628
+ type: 'error';
629
+ id: string;
630
+ message: string;
631
+ };
632
+ declare class ProofWorkerManager {
633
+ private worker;
634
+ private pending;
635
+ private terminated;
636
+ constructor(worker: Worker);
637
+ private handleMessage;
638
+ /**
639
+ * Generate a proof in the worker.
640
+ *
641
+ * @param signal - AbortSignal for cancellation. When aborted, the promise
642
+ * rejects with AbortError. Call terminate() for hard cancellation.
643
+ */
644
+ prove(circuitType: UPPCircuitType, inputs: UPPCircuitInputs, baseUrl: string, onProgress?: (stage: PlonkProvingStage, message: string) => void, signal?: AbortSignal): Promise<ProofResult>;
645
+ /**
646
+ * Hard-terminate the worker. All pending proofs are rejected.
647
+ */
648
+ terminate(): void;
649
+ }
650
+ /**
651
+ * Generate a UPP proof — uses a worker if provided, otherwise main-thread.
652
+ *
653
+ * This is the recommended entry point for proof generation. It provides a
654
+ * unified API regardless of whether a worker is available.
655
+ */
656
+ declare function generateUPPProofAsync(circuitType: UPPCircuitType, inputs: UPPCircuitInputs, baseUrl?: string, options?: {
657
+ onProgress?: (stage: PlonkProvingStage, message: string) => void;
658
+ signal?: AbortSignal;
659
+ worker?: ProofWorkerManager | null;
660
+ }): Promise<ProofResult>;
661
+
588
662
  /**
589
663
  * Swap Module
590
664
  *
@@ -1329,4 +1403,4 @@ declare function formatOutputForContract(note: NoteCreationResult): {
1329
1403
  encryptedNote: Hex;
1330
1404
  };
1331
1405
 
1332
- export { computeCancelKeyHash as $, type ASPProof as A, type StealthMetaAddress as B, type CircuitArtifacts as C, DEMO_ASP_ID as D, type EncryptedNote as E, type SwapFillEvent as F, type SwapFillParams as G, type SwapOrder as H, type SwapOrderEvent as I, type SwapOrderParams as J, type TransferContext as K, type TransferParams as L, type MergeParams as M, NOTE_VERSION as N, type TransferStage as O, type Proof as P, type UPPCircuitType as Q, RATE_PRECISION as R, STATE_TREE_DEPTH as S, type TransferBuildResult as T, type UPPCircuitInputs as U, type UPPTransferCircuitInputs as V, type UPPWithdrawCircuitInputs as W, type WithdrawParams as X, buildASPTree as Y, buildTransfer as Z, buildUPPTransferCircuitInputs as _, type ASPRoot as a, computeFillPercentage as a0, computeGiveAmount as a1, computeMultiOriginASPRoot as a2, computeNullifier as a3, computeRate as a4, computeSingleOriginASPRoot as a5, computeTakeAmount as a6, computeTotalBuyAmount as a7, createDemoASPRoot as a8, filterOrdersByASP as a9, useUPPAccount as aA, UPPAccountProvider as aB, type UPPAccountContextType as aC, type ProofSystemType as aD, type IndexerConfig as aE, type SignTypedDataFn as aF, ASP_TREE_DEPTH as aG, filterOrdersByTokenPair as aa, formatOutputForContract as ab, formatProofForContract as ac, formatRate as ad, generateASPProof as ae, generateCancelSecret as af, generateMultiOriginASPProof as ag, generateProof as ah, generateSingleOriginASPProof as ai, generateStealthProof as aj, generateUPPProof as ak, getCancelSecret as al, getMerkleProofsForNotes as am, getOwnOrderIds as an, getStealthCircuitArtifacts as ao, getUPPCircuitArtifacts as ap, isFillerASPAccepted as aq, isOrderActive as ar, removeCancelSecret as as, storeCancelSecret as at, syncMerkleTree as au, verifyASPProof as av, verifyProof as aw, type NoteCreationResult as ax, type PlonkProofStruct as ay, type ShieldedNote as az, ASP_TREE_DEPTH$1 as b, type CircuitType as c, type Commitment as d, DEMO_ASP_NAME as e, type MergeRecord as f, type MerkleProofWithNote as g, type Note as h, type NoteWithAmount as i, type Nullifier as j, type ProofResult as k, SWAP_EVENTS_ABI as l, SWAP_ORDER_CANCELLED_EVENT as m, SWAP_ORDER_CLAIMED_EVENT as n, SWAP_ORDER_FILLED_EVENT as o, SWAP_ORDER_PLACED_EVENT as p, type ShieldParams as q, type SpendableNote as r, type StarkNote as s, type StarkProof as t, type StarkStealthMetaAddress as u, type Stealth1x2CircuitInputs as v, type Stealth2x2CircuitInputs as w, type StealthAddress as x, type StealthCircuitInputs as y, type StealthCircuitType as z };
1406
+ export { type WithdrawParams as $, type ASPProof as A, type Stealth2x2CircuitInputs as B, type CircuitArtifacts as C, DEMO_ASP_ID as D, type EncryptedNote as E, type StealthAddress as F, type StealthCircuitInputs as G, type StealthCircuitType as H, type StealthMetaAddress as I, type SwapFillEvent as J, type SwapFillParams as K, type SwapOrder as L, type MergeParams as M, NOTE_VERSION as N, type SwapOrderEvent as O, type PlonkProvingStage as P, type SwapOrderParams as Q, RATE_PRECISION as R, STATE_TREE_DEPTH as S, type TransferBuildResult as T, type TransferContext as U, type TransferParams as V, type TransferStage as W, type UPPCircuitInputs as X, type UPPCircuitType as Y, type UPPTransferCircuitInputs as Z, type UPPWithdrawCircuitInputs as _, type ASPRoot as a, buildASPTree as a0, buildTransfer as a1, buildUPPTransferCircuitInputs as a2, computeCancelKeyHash as a3, computeFillPercentage as a4, computeGiveAmount as a5, computeMultiOriginASPRoot as a6, computeNullifier as a7, computeRate as a8, computeSingleOriginASPRoot as a9, verifyASPProof as aA, verifyProof as aB, type NoteCreationResult as aC, type PlonkProofStruct as aD, type ShieldedNote as aE, useUPPAccount as aF, UPPAccountProvider as aG, type UPPAccountContextType as aH, type ProofSystemType as aI, type IndexerConfig as aJ, type SignTypedDataFn as aK, ASP_TREE_DEPTH as aL, computeTakeAmount as aa, computeTotalBuyAmount as ab, createDemoASPRoot as ac, filterOrdersByASP as ad, filterOrdersByTokenPair as ae, formatOutputForContract as af, formatProofForContract as ag, formatRate as ah, generateASPProof as ai, generateCancelSecret as aj, generateMultiOriginASPProof as ak, generateProof as al, generateSingleOriginASPProof as am, generateStealthProof as an, generateUPPProof as ao, generateUPPProofAsync as ap, getCancelSecret as aq, getMerkleProofsForNotes as ar, getOwnOrderIds as as, getStealthCircuitArtifacts as at, getUPPCircuitArtifacts as au, isFillerASPAccepted as av, isOrderActive as aw, removeCancelSecret as ax, storeCancelSecret as ay, syncMerkleTree as az, ASP_TREE_DEPTH$1 as b, type CircuitType as c, type Commitment as d, DEMO_ASP_NAME as e, type MergeRecord as f, type MerkleProofWithNote as g, type Note as h, type NoteWithAmount as i, type Nullifier as j, type Proof as k, type ProofResult as l, ProofWorkerManager as m, type ProofWorkerRequest as n, type ProofWorkerResponse as o, SWAP_EVENTS_ABI as p, SWAP_ORDER_CANCELLED_EVENT as q, SWAP_ORDER_CLAIMED_EVENT as r, SWAP_ORDER_FILLED_EVENT as s, SWAP_ORDER_PLACED_EVENT as t, type ShieldParams as u, type SpendableNote as v, type StarkNote as w, type StarkProof as x, type StarkStealthMetaAddress as y, type Stealth1x2CircuitInputs as z };
@@ -585,6 +585,80 @@ declare function formatProofForContract(proof: Proof): {
585
585
  c: [bigint, bigint];
586
586
  };
587
587
 
588
+ /**
589
+ * Proof Worker Manager — off-main-thread PLONK proof generation.
590
+ *
591
+ * Manages a Web Worker that runs snarkjs proof generation, keeping the
592
+ * main thread (and UI) responsive during the 10-30s proving time.
593
+ *
594
+ * @example
595
+ * ```ts
596
+ * // Create worker (consumer handles bundler integration)
597
+ * const worker = new Worker(
598
+ * new URL('@permissionless-technologies/upp-sdk/worker', import.meta.url)
599
+ * )
600
+ * const manager = new ProofWorkerManager(worker)
601
+ *
602
+ * const result = await manager.prove('transfer', circuitInputs, '/circuits/',
603
+ * (stage, msg) => console.log(stage, msg)
604
+ * )
605
+ *
606
+ * // Cleanup
607
+ * manager.terminate()
608
+ * ```
609
+ */
610
+
611
+ interface ProofWorkerRequest {
612
+ type: 'prove';
613
+ id: string;
614
+ circuitType: string;
615
+ inputs: Record<string, any>;
616
+ baseUrl: string;
617
+ }
618
+ type ProofWorkerResponse = {
619
+ type: 'progress';
620
+ id: string;
621
+ stage: PlonkProvingStage;
622
+ message: string;
623
+ } | {
624
+ type: 'result';
625
+ id: string;
626
+ proof: ProofResult;
627
+ } | {
628
+ type: 'error';
629
+ id: string;
630
+ message: string;
631
+ };
632
+ declare class ProofWorkerManager {
633
+ private worker;
634
+ private pending;
635
+ private terminated;
636
+ constructor(worker: Worker);
637
+ private handleMessage;
638
+ /**
639
+ * Generate a proof in the worker.
640
+ *
641
+ * @param signal - AbortSignal for cancellation. When aborted, the promise
642
+ * rejects with AbortError. Call terminate() for hard cancellation.
643
+ */
644
+ prove(circuitType: UPPCircuitType, inputs: UPPCircuitInputs, baseUrl: string, onProgress?: (stage: PlonkProvingStage, message: string) => void, signal?: AbortSignal): Promise<ProofResult>;
645
+ /**
646
+ * Hard-terminate the worker. All pending proofs are rejected.
647
+ */
648
+ terminate(): void;
649
+ }
650
+ /**
651
+ * Generate a UPP proof — uses a worker if provided, otherwise main-thread.
652
+ *
653
+ * This is the recommended entry point for proof generation. It provides a
654
+ * unified API regardless of whether a worker is available.
655
+ */
656
+ declare function generateUPPProofAsync(circuitType: UPPCircuitType, inputs: UPPCircuitInputs, baseUrl?: string, options?: {
657
+ onProgress?: (stage: PlonkProvingStage, message: string) => void;
658
+ signal?: AbortSignal;
659
+ worker?: ProofWorkerManager | null;
660
+ }): Promise<ProofResult>;
661
+
588
662
  /**
589
663
  * Swap Module
590
664
  *
@@ -1329,4 +1403,4 @@ declare function formatOutputForContract(note: NoteCreationResult): {
1329
1403
  encryptedNote: Hex;
1330
1404
  };
1331
1405
 
1332
- export { computeCancelKeyHash as $, type ASPProof as A, type StealthMetaAddress as B, type CircuitArtifacts as C, DEMO_ASP_ID as D, type EncryptedNote as E, type SwapFillEvent as F, type SwapFillParams as G, type SwapOrder as H, type SwapOrderEvent as I, type SwapOrderParams as J, type TransferContext as K, type TransferParams as L, type MergeParams as M, NOTE_VERSION as N, type TransferStage as O, type Proof as P, type UPPCircuitType as Q, RATE_PRECISION as R, STATE_TREE_DEPTH as S, type TransferBuildResult as T, type UPPCircuitInputs as U, type UPPTransferCircuitInputs as V, type UPPWithdrawCircuitInputs as W, type WithdrawParams as X, buildASPTree as Y, buildTransfer as Z, buildUPPTransferCircuitInputs as _, type ASPRoot as a, computeFillPercentage as a0, computeGiveAmount as a1, computeMultiOriginASPRoot as a2, computeNullifier as a3, computeRate as a4, computeSingleOriginASPRoot as a5, computeTakeAmount as a6, computeTotalBuyAmount as a7, createDemoASPRoot as a8, filterOrdersByASP as a9, useUPPAccount as aA, UPPAccountProvider as aB, type UPPAccountContextType as aC, type ProofSystemType as aD, type IndexerConfig as aE, type SignTypedDataFn as aF, ASP_TREE_DEPTH as aG, filterOrdersByTokenPair as aa, formatOutputForContract as ab, formatProofForContract as ac, formatRate as ad, generateASPProof as ae, generateCancelSecret as af, generateMultiOriginASPProof as ag, generateProof as ah, generateSingleOriginASPProof as ai, generateStealthProof as aj, generateUPPProof as ak, getCancelSecret as al, getMerkleProofsForNotes as am, getOwnOrderIds as an, getStealthCircuitArtifacts as ao, getUPPCircuitArtifacts as ap, isFillerASPAccepted as aq, isOrderActive as ar, removeCancelSecret as as, storeCancelSecret as at, syncMerkleTree as au, verifyASPProof as av, verifyProof as aw, type NoteCreationResult as ax, type PlonkProofStruct as ay, type ShieldedNote as az, ASP_TREE_DEPTH$1 as b, type CircuitType as c, type Commitment as d, DEMO_ASP_NAME as e, type MergeRecord as f, type MerkleProofWithNote as g, type Note as h, type NoteWithAmount as i, type Nullifier as j, type ProofResult as k, SWAP_EVENTS_ABI as l, SWAP_ORDER_CANCELLED_EVENT as m, SWAP_ORDER_CLAIMED_EVENT as n, SWAP_ORDER_FILLED_EVENT as o, SWAP_ORDER_PLACED_EVENT as p, type ShieldParams as q, type SpendableNote as r, type StarkNote as s, type StarkProof as t, type StarkStealthMetaAddress as u, type Stealth1x2CircuitInputs as v, type Stealth2x2CircuitInputs as w, type StealthAddress as x, type StealthCircuitInputs as y, type StealthCircuitType as z };
1406
+ export { type WithdrawParams as $, type ASPProof as A, type Stealth2x2CircuitInputs as B, type CircuitArtifacts as C, DEMO_ASP_ID as D, type EncryptedNote as E, type StealthAddress as F, type StealthCircuitInputs as G, type StealthCircuitType as H, type StealthMetaAddress as I, type SwapFillEvent as J, type SwapFillParams as K, type SwapOrder as L, type MergeParams as M, NOTE_VERSION as N, type SwapOrderEvent as O, type PlonkProvingStage as P, type SwapOrderParams as Q, RATE_PRECISION as R, STATE_TREE_DEPTH as S, type TransferBuildResult as T, type TransferContext as U, type TransferParams as V, type TransferStage as W, type UPPCircuitInputs as X, type UPPCircuitType as Y, type UPPTransferCircuitInputs as Z, type UPPWithdrawCircuitInputs as _, type ASPRoot as a, buildASPTree as a0, buildTransfer as a1, buildUPPTransferCircuitInputs as a2, computeCancelKeyHash as a3, computeFillPercentage as a4, computeGiveAmount as a5, computeMultiOriginASPRoot as a6, computeNullifier as a7, computeRate as a8, computeSingleOriginASPRoot as a9, verifyASPProof as aA, verifyProof as aB, type NoteCreationResult as aC, type PlonkProofStruct as aD, type ShieldedNote as aE, useUPPAccount as aF, UPPAccountProvider as aG, type UPPAccountContextType as aH, type ProofSystemType as aI, type IndexerConfig as aJ, type SignTypedDataFn as aK, ASP_TREE_DEPTH as aL, computeTakeAmount as aa, computeTotalBuyAmount as ab, createDemoASPRoot as ac, filterOrdersByASP as ad, filterOrdersByTokenPair as ae, formatOutputForContract as af, formatProofForContract as ag, formatRate as ah, generateASPProof as ai, generateCancelSecret as aj, generateMultiOriginASPProof as ak, generateProof as al, generateSingleOriginASPProof as am, generateStealthProof as an, generateUPPProof as ao, generateUPPProofAsync as ap, getCancelSecret as aq, getMerkleProofsForNotes as ar, getOwnOrderIds as as, getStealthCircuitArtifacts as at, getUPPCircuitArtifacts as au, isFillerASPAccepted as av, isOrderActive as aw, removeCancelSecret as ax, storeCancelSecret as ay, syncMerkleTree as az, ASP_TREE_DEPTH$1 as b, type CircuitType as c, type Commitment as d, DEMO_ASP_NAME as e, type MergeRecord as f, type MerkleProofWithNote as g, type Note as h, type NoteWithAmount as i, type Nullifier as j, type Proof as k, type ProofResult as l, ProofWorkerManager as m, type ProofWorkerRequest as n, type ProofWorkerResponse as o, SWAP_EVENTS_ABI as p, SWAP_ORDER_CANCELLED_EVENT as q, SWAP_ORDER_CLAIMED_EVENT as r, SWAP_ORDER_FILLED_EVENT as s, SWAP_ORDER_PLACED_EVENT as t, type ShieldParams as u, type SpendableNote as v, type StarkNote as w, type StarkProof as x, type StarkStealthMetaAddress as y, type Stealth1x2CircuitInputs as z };
@@ -1,8 +1,8 @@
1
- export { buildTransfer, buildUPPTransferCircuitInputs, computeNullifier, formatOutputForContract, getMerkleProofsForNotes, syncMerkleTree } from './chunk-3I6ERQO3.js';
1
+ export { buildTransfer, buildUPPTransferCircuitInputs, computeNullifier, formatOutputForContract, getMerkleProofsForNotes, syncMerkleTree } from './chunk-GQ6JMNJI.js';
2
+ import './chunk-KRLRJ3HN.js';
2
3
  import './chunk-6IEYWJVS.js';
3
4
  import './chunk-GPF72JFR.js';
4
5
  import './chunk-5QSSX3KR.js';
5
- import './chunk-KRLRJ3HN.js';
6
6
  import './chunk-Z6ZWNWWR.js';
7
- //# sourceMappingURL=transfer-LGR44CER.js.map
8
- //# sourceMappingURL=transfer-LGR44CER.js.map
7
+ //# sourceMappingURL=transfer-LT2VGGPZ.js.map
8
+ //# sourceMappingURL=transfer-LT2VGGPZ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"transfer-LGR44CER.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"transfer-LT2VGGPZ.js"}
@@ -1,37 +1,37 @@
1
1
  'use strict';
2
2
 
3
- var chunk4MWEJDTR_cjs = require('./chunk-4MWEJDTR.cjs');
3
+ var chunk7Y6O4P2P_cjs = require('./chunk-7Y6O4P2P.cjs');
4
+ require('./chunk-RYEYGGE7.cjs');
4
5
  require('./chunk-XVIICZKW.cjs');
5
6
  require('./chunk-IIUKM5VE.cjs');
6
7
  require('./chunk-HEHXSV47.cjs');
7
- require('./chunk-RYEYGGE7.cjs');
8
8
  require('./chunk-G7VZBCD6.cjs');
9
9
 
10
10
 
11
11
 
12
12
  Object.defineProperty(exports, "buildTransfer", {
13
13
  enumerable: true,
14
- get: function () { return chunk4MWEJDTR_cjs.buildTransfer; }
14
+ get: function () { return chunk7Y6O4P2P_cjs.buildTransfer; }
15
15
  });
16
16
  Object.defineProperty(exports, "buildUPPTransferCircuitInputs", {
17
17
  enumerable: true,
18
- get: function () { return chunk4MWEJDTR_cjs.buildUPPTransferCircuitInputs; }
18
+ get: function () { return chunk7Y6O4P2P_cjs.buildUPPTransferCircuitInputs; }
19
19
  });
20
20
  Object.defineProperty(exports, "computeNullifier", {
21
21
  enumerable: true,
22
- get: function () { return chunk4MWEJDTR_cjs.computeNullifier; }
22
+ get: function () { return chunk7Y6O4P2P_cjs.computeNullifier; }
23
23
  });
24
24
  Object.defineProperty(exports, "formatOutputForContract", {
25
25
  enumerable: true,
26
- get: function () { return chunk4MWEJDTR_cjs.formatOutputForContract; }
26
+ get: function () { return chunk7Y6O4P2P_cjs.formatOutputForContract; }
27
27
  });
28
28
  Object.defineProperty(exports, "getMerkleProofsForNotes", {
29
29
  enumerable: true,
30
- get: function () { return chunk4MWEJDTR_cjs.getMerkleProofsForNotes; }
30
+ get: function () { return chunk7Y6O4P2P_cjs.getMerkleProofsForNotes; }
31
31
  });
32
32
  Object.defineProperty(exports, "syncMerkleTree", {
33
33
  enumerable: true,
34
- get: function () { return chunk4MWEJDTR_cjs.syncMerkleTree; }
34
+ get: function () { return chunk7Y6O4P2P_cjs.syncMerkleTree; }
35
35
  });
36
- //# sourceMappingURL=transfer-UZBU47HC.cjs.map
37
- //# sourceMappingURL=transfer-UZBU47HC.cjs.map
36
+ //# sourceMappingURL=transfer-OPGKWWX2.cjs.map
37
+ //# sourceMappingURL=transfer-OPGKWWX2.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"transfer-UZBU47HC.cjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"transfer-OPGKWWX2.cjs"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@permissionless-technologies/upp-sdk",
3
- "version": "0.4.13",
3
+ "version": "0.4.14",
4
4
  "description": "Universal Private Pool SDK - Privacy-preserving token operations for any ERC20",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -40,6 +40,10 @@
40
40
  "./stwo-prover": {
41
41
  "types": "./stwo-prover/pkg/upp_stwo_prover.d.ts",
42
42
  "import": "./stwo-prover/pkg/upp_stwo_prover.js"
43
+ },
44
+ "./worker": {
45
+ "types": "./dist/core/proof-worker-entry.d.ts",
46
+ "import": "./dist/core/proof-worker-entry.js"
43
47
  }
44
48
  },
45
49
  "files": [
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/stealth.ts","../src/core/swap.ts","../src/core/account.ts","../src/core/note-store.ts"],"names":["__export","ADDRESS_VERSION","STARK_ADDRESS_VERSION","STARK_STEALTH_ADDRESS_PREFIX","STEALTH_ADDRESS_PREFIX","bigintToBytes","bech32m","bytesToBigint","ownerHash","randomFieldElement","__esm","init_crypto","keccak256","encodeAbiParameters","parseAbiParameters","toHex","getAddress"],"mappings":"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","file":"chunk-23B5XSS4.cjs","sourcesContent":["/**\n * Stealth Address Utilities (Post-Quantum, Hash-Based)\n *\n * Implements stealth addresses using Poseidon hashes with bech32m encoding.\n * No BabyJubJub curve operations — ownership is proven via hash preimage.\n *\n * Address Format (bech32m):\n * 0zk1<version><chainId><ownerHash><viewingHash>\n *\n * Key Flow (self-shield):\n * 1. User derives ownerHash = Poseidon(spendingSecret)\n * 2. Commitment = Poseidon(amount, ownerHash, blinding, origin, token)\n * 3. Encrypt note with key derived from viewingSecret\n *\n * Key Flow (send to others, future):\n * 1. Decode recipient's stealth address (ownerHash, viewingHash)\n * 2. Generate per-note secret and derive ownerHash for the note\n * 3. Encrypt note so recipient's viewingSecret can decrypt\n */\n\nimport { bech32m } from 'bech32'\nimport {\n randomFieldElement,\n bigintToBytes,\n bytesToBigint,\n} from '../utils/crypto.js'\nimport type { MasterKeys, StarkMasterKeys, OneTimeKeys } from '../keys/types.js'\nimport type { M31Digest } from '../utils/keccak-m31.js'\n\n/**\n * Stealth address prefix\n */\nexport const STEALTH_ADDRESS_PREFIX = '0zk'\n\n/**\n * Address version (v2 = hash-based, post-quantum)\n */\nexport const ADDRESS_VERSION = 2\n\n/**\n * Maximum length for bech32m encoding\n */\nconst BECH32M_LIMIT = 1023\n\n/**\n * Encode a stealth address in bech32m format\n *\n * Format: 0zk1<version><chainId><ownerHash><viewingHash>\n *\n * @param ownerHash - Owner hash = Poseidon(spendingSecret)\n * @param viewingHash - Viewing hash = Poseidon(viewingSecret)\n * @param chainId - Optional chain ID (0 = any chain)\n * @returns bech32m encoded stealth address\n */\nexport function encodeStealthAddress(\n ownerHash: bigint,\n viewingHash: bigint,\n chainId: number = 0\n): string {\n // Build data buffer: version (1 byte) + chainId (4 bytes) + 2 * 32 bytes = 69 bytes\n const data = new Uint8Array(1 + 4 + 32 * 2)\n let offset = 0\n\n // Version\n data[offset++] = ADDRESS_VERSION\n\n // Chain ID (4 bytes, big-endian)\n data[offset++] = (chainId >> 24) & 0xff\n data[offset++] = (chainId >> 16) & 0xff\n data[offset++] = (chainId >> 8) & 0xff\n data[offset++] = chainId & 0xff\n\n // Owner hash (32 bytes)\n const ownerBytes = bigintToBytes(ownerHash, 32)\n data.set(ownerBytes, offset)\n offset += 32\n\n // Viewing hash (32 bytes)\n const viewingBytes = bigintToBytes(viewingHash, 32)\n data.set(viewingBytes, offset)\n\n // Convert to 5-bit words for bech32m\n const words = bech32m.toWords(data)\n\n // Encode with prefix\n return bech32m.encode(STEALTH_ADDRESS_PREFIX, words, BECH32M_LIMIT)\n}\n\n/**\n * Decode a bech32m stealth address\n *\n * @param address - bech32m encoded stealth address\n * @returns Decoded hash values\n */\nexport function decodeStealthAddress(address: string): {\n version: number\n chainId: number\n ownerHash: bigint\n viewingHash: bigint\n} {\n // Decode bech32m\n const decoded = bech32m.decode(address, BECH32M_LIMIT)\n\n // Verify prefix\n if (decoded.prefix !== STEALTH_ADDRESS_PREFIX) {\n throw new Error(`Invalid stealth address prefix: expected '${STEALTH_ADDRESS_PREFIX}', got '${decoded.prefix}'`)\n }\n\n // Convert from 5-bit words back to bytes\n const data = new Uint8Array(bech32m.fromWords(decoded.words))\n\n // Parse version\n let offset = 0\n const version = data[offset++]!\n\n if (version !== ADDRESS_VERSION) {\n throw new Error(`Unsupported address version: ${version}. Expected v${ADDRESS_VERSION} (hash-based).`)\n }\n\n // Parse chain ID\n const chainId =\n (data[offset++]! << 24) |\n (data[offset++]! << 16) |\n (data[offset++]! << 8) |\n data[offset++]!\n\n // Parse owner hash (32 bytes)\n const ownerHash = bytesToBigint(data.slice(offset, offset + 32))\n offset += 32\n\n // Parse viewing hash (32 bytes)\n const viewingHash = bytesToBigint(data.slice(offset, offset + 32))\n\n return {\n version,\n chainId,\n ownerHash,\n viewingHash,\n }\n}\n\n/**\n * Validate a stealth address format\n */\nexport function isValidStealthAddress(address: string): boolean {\n try {\n decodeStealthAddress(address)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Generate stealth address from master keys\n */\nexport function generateStealthAddress(keys: MasterKeys, chainId: number = 0): string {\n return encodeStealthAddress(keys.ownerHash, keys.viewingHash, chainId)\n}\n\n/**\n * Create one-time keys for a transaction (hash-based)\n *\n * For self-shield: the user uses their own spendingSecret directly\n * as the ownerSecret, producing ownerHash = Poseidon(spendingSecret).\n *\n * For sending to others (future): generate a random oneTimeSecret\n * and derive ownerHash = Poseidon(oneTimeSecret).\n *\n * @param recipientOwnerHash - Recipient's owner hash (for verification)\n * @param selfSecret - If self-shield, the user's spending secret\n * @returns One-time keys for the note\n */\nexport async function createOneTimeKeys(\n _recipientOwnerHash?: bigint,\n selfSecret?: bigint,\n): Promise<OneTimeKeys> {\n const { poseidon } = await import('../utils/poseidon.js')\n\n if (selfSecret !== undefined) {\n // Self-shield: use own spending secret\n const ownerHash = await poseidon([selfSecret])\n return {\n oneTimeSecret: selfSecret,\n ownerHash,\n }\n }\n\n // Generate random one-time secret for the note\n const oneTimeSecret = randomFieldElement()\n const ownerHash = await poseidon([oneTimeSecret])\n\n return {\n oneTimeSecret,\n ownerHash,\n }\n}\n\n/**\n * Verify ownership of a note by checking hash preimage\n *\n * @param secret - Claimed spending secret\n * @param expectedOwnerHash - Owner hash from the note commitment\n * @returns True if the secret hashes to the expected owner hash\n */\nexport async function verifyOwnership(\n secret: bigint,\n expectedOwnerHash: bigint\n): Promise<boolean> {\n const { poseidon } = await import('../utils/poseidon.js')\n const computedHash = await poseidon([secret])\n return computedHash === expectedOwnerHash\n}\n\n/**\n * Compute shared secret for note encryption/decryption (hash-based)\n *\n * For self-shield: just uses the viewing secret directly.\n * For sending to others (future): use Poseidon(viewingSecret, recipientViewingHash)\n *\n * @param viewingSecret - Sender's or recipient's viewing secret\n * @param nonce - Optional nonce for key derivation\n * @returns Encryption key as bigint\n */\nexport async function computeNoteEncryptionKey(\n viewingSecret: bigint,\n nonce?: bigint\n): Promise<bigint> {\n const { poseidon } = await import('../utils/poseidon.js')\n if (nonce !== undefined) {\n return poseidon([viewingSecret, nonce])\n }\n return poseidon([viewingSecret])\n}\n\n// =========================================================================\n// STARK Stealth Addresses (0zs prefix, M31/Keccak-based)\n// =========================================================================\n\n/**\n * STARK stealth address prefix\n */\nexport const STARK_STEALTH_ADDRESS_PREFIX = '0zs'\n\n/**\n * STARK address version (v1 = M31/Keccak)\n */\nexport const STARK_ADDRESS_VERSION = 1\n\n/**\n * Encode a STARK stealth address in bech32m format\n *\n * Format: 0zs1<version><chainId><ownerHash[0..3]><viewingHash[0..3]>\n *\n * Each M31 element is encoded as 4 bytes (little-endian).\n * Total data: 1 (version) + 4 (chainId) + 16 (ownerHash) + 16 (viewingHash) = 37 bytes.\n *\n * @param ownerHash - 4 M31 elements: keccak_m31(starkSecret)\n * @param viewingHash - 4 M31 elements: keccak_m31(starkViewingSecret)\n * @param chainId - Optional chain ID (0 = any chain)\n */\nexport function encodeStarkStealthAddress(\n ownerHash: M31Digest,\n viewingHash: M31Digest,\n chainId: number = 0\n): string {\n const data = new Uint8Array(1 + 4 + 16 + 16) // 37 bytes\n let offset = 0\n\n // Version\n data[offset++] = STARK_ADDRESS_VERSION\n\n // Chain ID (4 bytes, big-endian)\n data[offset++] = (chainId >> 24) & 0xff\n data[offset++] = (chainId >> 16) & 0xff\n data[offset++] = (chainId >> 8) & 0xff\n data[offset++] = chainId & 0xff\n\n // Owner hash: 4 M31 elements, each 4 bytes LE\n for (let i = 0; i < 4; i++) {\n const val = Number(ownerHash[i]!)\n data[offset++] = val & 0xff\n data[offset++] = (val >> 8) & 0xff\n data[offset++] = (val >> 16) & 0xff\n data[offset++] = (val >> 24) & 0xff\n }\n\n // Viewing hash: 4 M31 elements, each 4 bytes LE\n for (let i = 0; i < 4; i++) {\n const val = Number(viewingHash[i]!)\n data[offset++] = val & 0xff\n data[offset++] = (val >> 8) & 0xff\n data[offset++] = (val >> 16) & 0xff\n data[offset++] = (val >> 24) & 0xff\n }\n\n const words = bech32m.toWords(data)\n return bech32m.encode(STARK_STEALTH_ADDRESS_PREFIX, words, BECH32M_LIMIT)\n}\n\n/**\n * Decode a STARK stealth address (0zs prefix)\n */\nexport function decodeStarkStealthAddress(address: string): {\n version: number\n chainId: number\n ownerHash: M31Digest\n viewingHash: M31Digest\n} {\n const decoded = bech32m.decode(address, BECH32M_LIMIT)\n\n if (decoded.prefix !== STARK_STEALTH_ADDRESS_PREFIX) {\n throw new Error(\n `Invalid STARK stealth address prefix: expected '${STARK_STEALTH_ADDRESS_PREFIX}', got '${decoded.prefix}'`\n )\n }\n\n const data = new Uint8Array(bech32m.fromWords(decoded.words))\n let offset = 0\n\n const version = data[offset++]!\n if (version !== STARK_ADDRESS_VERSION) {\n throw new Error(\n `Unsupported STARK address version: ${version}. Expected v${STARK_ADDRESS_VERSION}.`\n )\n }\n\n // Chain ID\n const chainId =\n (data[offset++]! << 24) |\n (data[offset++]! << 16) |\n (data[offset++]! << 8) |\n data[offset++]!\n\n // Owner hash: 4 M31 LE uint32s\n const ownerHash: bigint[] = []\n for (let i = 0; i < 4; i++) {\n const val =\n data[offset]! |\n (data[offset + 1]! << 8) |\n (data[offset + 2]! << 16) |\n (data[offset + 3]! << 24)\n ownerHash.push(BigInt(val >>> 0))\n offset += 4\n }\n\n // Viewing hash: 4 M31 LE uint32s\n const viewingHash: bigint[] = []\n for (let i = 0; i < 4; i++) {\n const val =\n data[offset]! |\n (data[offset + 1]! << 8) |\n (data[offset + 2]! << 16) |\n (data[offset + 3]! << 24)\n viewingHash.push(BigInt(val >>> 0))\n offset += 4\n }\n\n return {\n version,\n chainId,\n ownerHash: ownerHash as unknown as M31Digest,\n viewingHash: viewingHash as unknown as M31Digest,\n }\n}\n\n/**\n * Validate a STARK stealth address format\n */\nexport function isValidStarkStealthAddress(address: string): boolean {\n try {\n decodeStarkStealthAddress(address)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Generate a STARK stealth address from STARK master keys\n */\nexport function generateStarkStealthAddress(\n keys: StarkMasterKeys,\n chainId: number = 0\n): string {\n return encodeStarkStealthAddress(keys.starkOwnerHash, keys.starkViewingHash, chainId)\n}\n\n/**\n * Detect whether an address is SNARK (0zk) or STARK (0zs)\n */\nexport function detectAddressType(address: string): 'snark' | 'stark' | 'unknown' {\n if (address.startsWith(STEALTH_ADDRESS_PREFIX + '1')) return 'snark'\n if (address.startsWith(STARK_STEALTH_ADDRESS_PREFIX + '1')) return 'stark'\n return 'unknown'\n}\n","/**\n * Swap Module\n *\n * Core logic for building and interacting with the UPP in-pool swap order book.\n * Framework-agnostic (no React). Reuses withdraw verifier for proofs.\n */\n\nimport { type Address, type Hex, encodeAbiParameters, keccak256, parseAbiParameters, toHex } from 'viem'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Swap order as stored on-chain\n */\nexport interface SwapOrder {\n /** Order ID (= maker's nullifier) */\n orderId: Hex\n /** Token being sold */\n sellToken: Address\n /** Original total sell amount */\n sellAmount: bigint\n /** Remaining sell amount (decremented on each fill) */\n remainingSellAmount: bigint\n /** Token the maker wants to receive */\n buyToken: Address\n /** Price: buyToken per sellToken (1e18 fixed-point) */\n rate: bigint\n /** Accumulated buy token amount from fills */\n accumulatedBuyAmount: bigint\n /** Maker's ASP ID (public, filterable by takers) */\n makerAspId: bigint\n /** Required filler ASP (0 = any) */\n requiredFillerAspId: bigint\n /** Block number after which order expires */\n expiry: bigint\n /** Whether the maker has claimed */\n claimed: boolean\n /** Whether the order was cancelled */\n cancelled: boolean\n}\n\n/**\n * Parameters to place a swap order\n */\nexport interface SwapOrderParams {\n /** Token to sell */\n sellToken: Address\n /** Amount to sell */\n sellAmount: bigint\n /** Token to buy */\n buyToken: Address\n /** Price: buyToken per sellToken (1e18 fixed-point) */\n rate: bigint\n /** Required filler ASP (0n = accept any) */\n requiredFillerAspId?: bigint\n /** Number of blocks until expiry (from current block) */\n expiryBlocks: bigint\n}\n\n/**\n * Parameters to fill a swap order\n */\nexport interface SwapFillParams {\n /** The order to fill */\n orderId: Hex\n /** How much sellToken the filler wants (≤ remaining) */\n takeAmount: bigint\n}\n\n/**\n * Swap order from event log\n */\nexport interface SwapOrderEvent {\n orderId: Hex\n sellToken: Address\n buyToken: Address\n sellAmount: bigint\n rate: bigint\n makerAspId: bigint\n requiredFillerAspId: bigint\n expiry: bigint\n blockNumber: bigint\n /** On-chain remaining sell amount (populated by useSwapOrderBook) */\n remainingSellAmount?: bigint\n /** Whether the order has been claimed */\n claimed?: boolean\n /** Whether the order has been cancelled */\n cancelled?: boolean\n}\n\n/**\n * Swap fill from event log\n */\nexport interface SwapFillEvent {\n orderId: Hex\n fillerNullifier: Hex\n takeAmount: bigint\n giveAmount: bigint\n fillerAspId: bigint\n blockNumber: bigint\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** 1e18 fixed-point precision for swap rates */\nexport const RATE_PRECISION = 10n ** 18n\n\n// ============================================================================\n// Event ABIs (for indexing swap events)\n// ============================================================================\n\nexport const SWAP_ORDER_PLACED_EVENT = {\n type: 'event',\n name: 'SwapOrderPlaced',\n inputs: [\n { name: 'orderId', type: 'bytes32', indexed: true },\n { name: 'sellToken', type: 'address', indexed: true },\n { name: 'buyToken', type: 'address', indexed: true },\n { name: 'sellAmount', type: 'uint256', indexed: false },\n { name: 'rate', type: 'uint256', indexed: false },\n { name: 'makerAspId', type: 'uint256', indexed: false },\n { name: 'requiredFillerAspId', type: 'uint256', indexed: false },\n { name: 'expiry', type: 'uint256', indexed: false },\n ],\n} as const\n\nexport const SWAP_ORDER_FILLED_EVENT = {\n type: 'event',\n name: 'SwapOrderFilled',\n inputs: [\n { name: 'orderId', type: 'bytes32', indexed: true },\n { name: 'fillerNullifier', type: 'bytes32', indexed: true },\n { name: 'takeAmount', type: 'uint256', indexed: false },\n { name: 'giveAmount', type: 'uint256', indexed: false },\n { name: 'fillerAspId', type: 'uint256', indexed: false },\n ],\n} as const\n\nexport const SWAP_ORDER_CLAIMED_EVENT = {\n type: 'event',\n name: 'SwapOrderClaimed',\n inputs: [\n { name: 'orderId', type: 'bytes32', indexed: true },\n { name: 'accumulatedBuyAmount', type: 'uint256', indexed: false },\n { name: 'refundedSellAmount', type: 'uint256', indexed: false },\n ],\n} as const\n\nexport const SWAP_ORDER_CANCELLED_EVENT = {\n type: 'event',\n name: 'SwapOrderCancelled',\n inputs: [\n { name: 'orderId', type: 'bytes32', indexed: true },\n { name: 'refundedSellAmount', type: 'uint256', indexed: false },\n ],\n} as const\n\nexport const SWAP_EVENTS_ABI = [\n SWAP_ORDER_PLACED_EVENT,\n SWAP_ORDER_FILLED_EVENT,\n SWAP_ORDER_CLAIMED_EVENT,\n SWAP_ORDER_CANCELLED_EVENT,\n] as const\n\n// ============================================================================\n// Rate Calculations\n// ============================================================================\n\n/**\n * Compute the giveAmount (buyToken) for a given takeAmount (sellToken) at a rate.\n * giveAmount = (takeAmount * rate) / 1e18\n */\nexport function computeGiveAmount(takeAmount: bigint, rate: bigint): bigint {\n return (takeAmount * rate) / RATE_PRECISION\n}\n\n/**\n * Compute the maximum takeAmount for a given giveAmount and rate.\n * takeAmount = (giveAmount * 1e18) / rate\n */\nexport function computeTakeAmount(giveAmount: bigint, rate: bigint): bigint {\n if (rate === 0n) throw new Error('Rate cannot be zero')\n return (giveAmount * RATE_PRECISION) / rate\n}\n\n/**\n * Compute rate from a desired trade: I want `buyAmount` of buyToken for `sellAmount` of sellToken.\n * rate = (buyAmount * 1e18) / sellAmount\n */\nexport function computeRate(sellAmount: bigint, buyAmount: bigint): bigint {\n if (sellAmount === 0n) throw new Error('Sell amount cannot be zero')\n return (buyAmount * RATE_PRECISION) / sellAmount\n}\n\n/**\n * Format a rate for human display.\n * Returns a string like \"0.0005\" for rate = 500000000000000n (0.0005e18)\n */\nexport function formatRate(rate: bigint, decimals: number = 6): string {\n const whole = rate / RATE_PRECISION\n const frac = rate % RATE_PRECISION\n const fracStr = frac.toString().padStart(18, '0').slice(0, decimals)\n return `${whole}.${fracStr}`\n}\n\n// ============================================================================\n// Cancel Key Management\n// ============================================================================\n\n/**\n * Generate a cancel key hash from a secret.\n * The secret should be a random 32-byte value stored by the maker.\n */\nexport function computeCancelKeyHash(cancelSecret: Hex): Hex {\n return keccak256(encodeAbiParameters(\n parseAbiParameters('bytes32'),\n [cancelSecret]\n ))\n}\n\n/**\n * Generate a random cancel secret.\n */\nexport function generateCancelSecret(): Hex {\n const bytes = new Uint8Array(32)\n crypto.getRandomValues(bytes)\n return toHex(bytes)\n}\n\n// ============================================================================\n// Order Filtering\n// ============================================================================\n\n/**\n * Filter orders by ASP: only show orders from makers on acceptable ASPs.\n */\nexport function filterOrdersByASP(\n orders: SwapOrderEvent[],\n acceptableAspIds: bigint[]\n): SwapOrderEvent[] {\n const aspSet = new Set(acceptableAspIds.map(id => id.toString()))\n return orders.filter(o => aspSet.has(o.makerAspId.toString()))\n}\n\n/**\n * Filter orders by token pair.\n */\nexport function filterOrdersByTokenPair(\n orders: SwapOrderEvent[],\n sellToken: Address,\n buyToken: Address\n): SwapOrderEvent[] {\n const sell = sellToken.toLowerCase()\n const buy = buyToken.toLowerCase()\n return orders.filter(\n o => o.sellToken.toLowerCase() === sell && o.buyToken.toLowerCase() === buy\n )\n}\n\n/**\n * Check if a filler's ASP is accepted by an order.\n */\nexport function isFillerASPAccepted(order: SwapOrder | SwapOrderEvent, fillerAspId: bigint): boolean {\n const required = 'requiredFillerAspId' in order ? order.requiredFillerAspId : 0n\n return required === 0n || required === fillerAspId\n}\n\n// ============================================================================\n// Cancel Secret Persistence (localStorage)\n// ============================================================================\n\nconst CANCEL_SECRET_PREFIX = 'upp_swap_cancel_'\n\nfunction cancelKey(account: string, orderId: Hex): string {\n return `${CANCEL_SECRET_PREFIX}${account.toLowerCase()}_${orderId}`\n}\n\n/**\n * Store a cancel secret in localStorage, scoped by wallet address.\n * Must be called after placing a swap order.\n */\nexport function storeCancelSecret(orderId: Hex, cancelSecret: Hex, account?: string): void {\n if (typeof localStorage === 'undefined') return\n if (account) {\n localStorage.setItem(cancelKey(account, orderId), cancelSecret)\n }\n // Also store unscoped for backward compat\n localStorage.setItem(`${CANCEL_SECRET_PREFIX}${orderId}`, cancelSecret)\n}\n\n/**\n * Retrieve a cancel secret from localStorage.\n * Returns null if not found (e.g. order was placed by someone else).\n */\nexport function getCancelSecret(orderId: Hex, account?: string): Hex | null {\n if (typeof localStorage === 'undefined') return null\n if (account) {\n const scoped = localStorage.getItem(cancelKey(account, orderId))\n if (scoped) return scoped as Hex\n }\n // Fall back to unscoped key\n return localStorage.getItem(`${CANCEL_SECRET_PREFIX}${orderId}`) as Hex | null\n}\n\n/**\n * Remove a cancel secret from localStorage (after claim or cancel).\n */\nexport function removeCancelSecret(orderId: Hex, account?: string): void {\n if (typeof localStorage === 'undefined') return\n if (account) {\n localStorage.removeItem(cancelKey(account, orderId))\n }\n localStorage.removeItem(`${CANCEL_SECRET_PREFIX}${orderId}`)\n}\n\n/**\n * Get all order IDs for a specific wallet address.\n * Falls back to all cancel secrets if no account provided (backward compat).\n */\nexport function getOwnOrderIds(account?: string): Hex[] {\n if (typeof localStorage === 'undefined') return []\n const prefix = account\n ? `${CANCEL_SECRET_PREFIX}${account.toLowerCase()}_`\n : CANCEL_SECRET_PREFIX\n const ids: Hex[] = []\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i)\n if (key?.startsWith(prefix)) {\n ids.push(key.slice(prefix.length) as Hex)\n }\n }\n return ids\n}\n\n// ============================================================================\n// Order Status Helpers\n// ============================================================================\n\n/**\n * Check if an order is still active (not claimed, not cancelled, not expired).\n */\nexport function isOrderActive(order: SwapOrder, currentBlock: bigint): boolean {\n return !order.claimed && !order.cancelled && currentBlock <= order.expiry && order.remainingSellAmount > 0n\n}\n\n/**\n * Compute the total buyToken amount the maker would receive for a full fill.\n */\nexport function computeTotalBuyAmount(sellAmount: bigint, rate: bigint): bigint {\n return computeGiveAmount(sellAmount, rate)\n}\n\n/**\n * Compute fill percentage (0-100) for display.\n */\nexport function computeFillPercentage(order: SwapOrder): number {\n if (order.sellAmount === 0n) return 0\n const filled = order.sellAmount - order.remainingSellAmount\n return Number((filled * 10000n) / order.sellAmount) / 100\n}\n","/**\n * Account Adapter — Pluggable account creation and persistence\n *\n * Abstracts how master keys are derived/loaded/stored.\n * The SDK doesn't care if keys come from a wallet signature,\n * seed phrase, hardware wallet, or external KMS.\n *\n * Persistence is handled via StorageAdapter (IndexedDB, localStorage, etc.)\n */\n\nimport type { MasterKeys, StarkMasterKeys } from '../keys/types.js'\nimport type { StorageAdapter } from '../indexer/types.js'\nimport { toHex } from 'viem'\n\n// ============================================================================\n// Interface\n// ============================================================================\n\n/**\n * Account adapter interface — pluggable key source.\n *\n * Implement this to bring your own key derivation:\n * - StorableAccountAdapter: persists keys via StorageAdapter (built-in)\n * - DirectAccountAdapter: pre-derived keys, no persistence (built-in, for testing)\n * - Custom: seed phrase, hardware wallet, external KMS\n */\nexport interface IAccountAdapter {\n /** Load persisted keys (returns null if no saved account) */\n load(): Promise<{ keys: MasterKeys; starkKeys?: StarkMasterKeys } | null>\n /** Save keys to storage */\n save(keys: MasterKeys, starkKeys?: StarkMasterKeys): Promise<void>\n /** Clear persisted keys */\n clear(): Promise<void>\n}\n\n// ============================================================================\n// Serialization\n// ============================================================================\n\ninterface SerializedAccount {\n version: 3\n spendingSecret: string\n ownerHash: string\n viewingSecret: string\n viewingHash: string\n starkSecret?: string[]\n starkOwnerHash?: string[]\n starkViewingSecret?: string[]\n starkViewingHash?: string[]\n}\n\nfunction serializeAccount(keys: MasterKeys, starkKeys?: StarkMasterKeys): SerializedAccount {\n return {\n version: 3,\n spendingSecret: toHex(keys.spendingSecret, { size: 32 }),\n ownerHash: toHex(keys.ownerHash, { size: 32 }),\n viewingSecret: toHex(keys.viewingSecret, { size: 32 }),\n viewingHash: toHex(keys.viewingHash, { size: 32 }),\n ...(starkKeys ? {\n starkSecret: starkKeys.starkSecret.map(v => v.toString()),\n starkOwnerHash: starkKeys.starkOwnerHash.map(v => v.toString()),\n starkViewingSecret: starkKeys.starkViewingSecret.map(v => v.toString()),\n starkViewingHash: starkKeys.starkViewingHash.map(v => v.toString()),\n } : {}),\n }\n}\n\nfunction deserializeAccount(data: SerializedAccount): { keys: MasterKeys; starkKeys?: StarkMasterKeys } {\n if (data.version !== 3 || !data.spendingSecret) {\n throw new Error('Invalid or outdated account data')\n }\n\n const keys: MasterKeys = {\n spendingSecret: BigInt(data.spendingSecret),\n ownerHash: BigInt(data.ownerHash),\n viewingSecret: BigInt(data.viewingSecret),\n viewingHash: BigInt(data.viewingHash),\n }\n\n let starkKeys: StarkMasterKeys | undefined\n if (data.starkSecret) {\n starkKeys = {\n starkSecret: data.starkSecret.map(s => BigInt(s)) as any,\n starkOwnerHash: data.starkOwnerHash!.map(s => BigInt(s)) as any,\n starkViewingSecret: data.starkViewingSecret!.map(s => BigInt(s)) as any,\n starkViewingHash: data.starkViewingHash!.map(s => BigInt(s)) as any,\n }\n }\n\n return { keys, starkKeys }\n}\n\n// ============================================================================\n// StorableAccountAdapter — persists via StorageAdapter\n// ============================================================================\n\n/**\n * Account adapter that persists keys via a pluggable StorageAdapter.\n *\n * Works with IndexedDB, localStorage, memory, Redis, Postgres — anything\n * that implements StorageAdapter.\n *\n * @example\n * ```ts\n * const storage = createAutoAdapter('upp_account')\n * const adapter = new StorableAccountAdapter(storage, ethAddress)\n * const saved = await adapter.load()\n * if (!saved) {\n * const keys = await deriveKeysFromSignature(sig)\n * await adapter.save(keys, starkKeys)\n * }\n * ```\n */\nexport class StorableAccountAdapter implements IAccountAdapter {\n private storageKey: string\n\n constructor(\n private storage: StorageAdapter,\n ethAddress: string,\n ) {\n this.storageKey = `account_${ethAddress.toLowerCase()}`\n }\n\n async load(): Promise<{ keys: MasterKeys; starkKeys?: StarkMasterKeys } | null> {\n const data = await this.storage.get<SerializedAccount>(this.storageKey)\n if (!data) return null\n try {\n return deserializeAccount(data)\n } catch {\n // Corrupt or outdated — clear it\n await this.storage.delete(this.storageKey)\n return null\n }\n }\n\n async save(keys: MasterKeys, starkKeys?: StarkMasterKeys): Promise<void> {\n const serialized = serializeAccount(keys, starkKeys)\n await this.storage.set(this.storageKey, serialized)\n }\n\n async clear(): Promise<void> {\n await this.storage.delete(this.storageKey)\n }\n}\n\n// ============================================================================\n// DirectAccountAdapter — no persistence (testing, KMS)\n// ============================================================================\n\n/**\n * Direct account adapter — accepts pre-derived keys, no persistence.\n *\n * @example\n * ```ts\n * const adapter = new DirectAccountAdapter(masterKeys, starkKeys)\n * ```\n */\nexport class DirectAccountAdapter implements IAccountAdapter {\n constructor(\n private keys: MasterKeys,\n private starkKeys?: StarkMasterKeys,\n ) {}\n\n async load() {\n return { keys: this.keys, starkKeys: this.starkKeys }\n }\n\n async save(): Promise<void> {\n // No-op — keys are in memory only\n }\n\n async clear(): Promise<void> {\n // No-op\n }\n}\n","/**\n * NoteStore — Single source of truth for note state\n *\n * Framework-agnostic. Uses StorageAdapter for persistence.\n * Handles deduplication, status management, balance calculation.\n *\n * Usage:\n * const store = new NoteStore(createMemoryAdapter())\n * await store.load()\n * store.addNote(note) // returns false if duplicate\n * store.getBalance() // sum of unspent notes\n */\n\nimport type { StorageAdapter } from '../indexer/types.js'\nimport { getAddress } from 'viem'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type NoteStatus = 'pending' | 'confirmed' | 'spent'\nexport type ProofSystem = 'snark' | 'stark'\n\nexport interface ShieldedNote {\n amount: bigint\n blinding: bigint\n commitment: string\n ownerSecret: string\n ownerHash: string\n leafIndex: number\n origin: string\n token: string\n txHash?: string\n status: NoteStatus\n timestamp: number\n proofSystem?: ProofSystem\n}\n\n/** Serialized format for storage (bigints as strings) */\ninterface SerializedNote {\n amount: string\n blinding: string\n commitment: string\n ownerSecret: string\n ownerHash: string\n leafIndex: number\n origin: string\n token: string\n txHash?: string\n status: NoteStatus\n timestamp: number\n proofSystem?: ProofSystem\n}\n\nexport interface INoteStore {\n getNotes(): ShieldedNote[]\n getUnspentNotes(proofSystem?: ProofSystem): ShieldedNote[]\n getBalance(token?: string, proofSystem?: ProofSystem): bigint\n addNote(note: ShieldedNote): boolean\n addNotes(notes: ShieldedNote[]): number\n markSpent(commitment: string): void\n unmarkSpent(commitment: string): void\n updateLeafIndex(commitment: string, leafIndex: number): void\n load(): Promise<void>\n persist(): Promise<void>\n clear(): Promise<void>\n onChange(callback: () => void): () => void\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\nexport class NoteStore implements INoteStore {\n private notes: ShieldedNote[] = []\n private commitmentSet = new Set<string>()\n private listeners = new Set<() => void>()\n private dirty = false\n\n constructor(\n private storage: StorageAdapter,\n private storageKey: string = 'notes',\n ) {}\n\n // ---------- Queries ----------\n\n getNotes(): ShieldedNote[] {\n return [...this.notes]\n }\n\n getUnspentNotes(proofSystem?: ProofSystem): ShieldedNote[] {\n let result = this.notes.filter(n => n.status !== 'spent')\n if (proofSystem) {\n result = result.filter(n => (n.proofSystem ?? 'snark') === proofSystem)\n }\n return result\n }\n\n getBalance(token?: string, proofSystem?: ProofSystem): bigint {\n let notes = this.getUnspentNotes(proofSystem)\n if (token) {\n const normalized = token.toLowerCase()\n notes = notes.filter(n => n.token.toLowerCase() === normalized)\n }\n return notes.reduce((sum, n) => sum + n.amount, 0n)\n }\n\n // ---------- Mutations ----------\n\n /**\n * Add a note. Returns false if duplicate (by commitment).\n * Normalizes token and origin addresses.\n */\n addNote(note: ShieldedNote): boolean {\n const key = note.commitment.toLowerCase()\n if (this.commitmentSet.has(key)) return false\n\n // Normalize addresses\n const normalized: ShieldedNote = {\n ...note,\n commitment: note.commitment.toLowerCase(),\n origin: safeGetAddress(note.origin),\n token: safeGetAddress(note.token),\n }\n\n this.notes.push(normalized)\n this.commitmentSet.add(key)\n this.dirty = true\n this.notify()\n return true\n }\n\n /**\n * Add multiple notes. Returns count of actually added (non-duplicate).\n */\n addNotes(notes: ShieldedNote[]): number {\n let added = 0\n for (const note of notes) {\n if (this.addNote(note)) added++\n }\n return added\n }\n\n /**\n * Mark a note as spent (optimistic — syncNotes reconciles via nullifier check).\n */\n markSpent(commitment: string): void {\n const key = commitment.toLowerCase()\n const note = this.notes.find(n => n.commitment.toLowerCase() === key)\n if (note && note.status !== 'spent') {\n note.status = 'spent'\n this.dirty = true\n this.notify()\n }\n }\n\n /**\n * Un-mark a note as spent (reconciliation: nullifier not found on-chain).\n */\n unmarkSpent(commitment: string): void {\n const key = commitment.toLowerCase()\n const note = this.notes.find(n => n.commitment.toLowerCase() === key)\n if (note && note.status === 'spent') {\n note.status = 'confirmed'\n this.dirty = true\n this.notify()\n }\n }\n\n /**\n * Update the leafIndex for a note (e.g., after confirming on-chain).\n */\n updateLeafIndex(commitment: string, leafIndex: number): void {\n const key = commitment.toLowerCase()\n const note = this.notes.find(n => n.commitment.toLowerCase() === key)\n if (note && note.leafIndex !== leafIndex) {\n note.leafIndex = leafIndex\n this.dirty = true\n this.notify()\n }\n }\n\n // ---------- Persistence ----------\n\n async load(): Promise<void> {\n const serialized = await this.storage.get<SerializedNote[]>(this.storageKey)\n if (!serialized || !Array.isArray(serialized)) {\n this.notes = []\n this.commitmentSet.clear()\n return\n }\n\n // Deduplicate on load — prevents persisted duplicates from propagating\n this.notes = []\n this.commitmentSet.clear()\n let deduped = 0\n for (const s of serialized) {\n const note = deserializeNote(s)\n const key = note.commitment.toLowerCase()\n if (this.commitmentSet.has(key)) { deduped++; continue }\n this.commitmentSet.add(key)\n this.notes.push(note)\n }\n if (deduped > 0) {\n console.log(`[NoteStore] Removed ${deduped} duplicate notes on load`)\n this.dirty = true // will persist the cleaned version\n } else {\n this.dirty = false\n }\n }\n\n async persist(): Promise<void> {\n if (!this.dirty) return\n const serialized = this.notes.map(serializeNote)\n await this.storage.set(this.storageKey, serialized)\n this.dirty = false\n }\n\n async clear(): Promise<void> {\n this.notes = []\n this.commitmentSet.clear()\n this.dirty = false\n await this.storage.delete(this.storageKey)\n this.notify()\n }\n\n // ---------- Events ----------\n\n onChange(callback: () => void): () => void {\n this.listeners.add(callback)\n return () => this.listeners.delete(callback)\n }\n\n private notify(): void {\n for (const listener of this.listeners) {\n listener()\n }\n }\n}\n\n// ============================================================================\n// Serialization\n// ============================================================================\n\nfunction serializeNote(note: ShieldedNote): SerializedNote {\n return {\n ...note,\n amount: note.amount.toString(),\n blinding: note.blinding.toString(),\n }\n}\n\nfunction deserializeNote(s: SerializedNote): ShieldedNote {\n return {\n ...s,\n amount: BigInt(s.amount),\n blinding: BigInt(s.blinding),\n proofSystem: s.proofSystem ?? 'snark',\n }\n}\n\nfunction safeGetAddress(addr: string): string {\n try {\n return getAddress(addr)\n } catch {\n return addr // return as-is if not a valid address (e.g., bigint-encoded origin)\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/stealth.ts","../src/core/swap.ts","../src/core/account.ts","../src/core/note-store.ts"],"names":["ownerHash","toHex"],"mappings":"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","file":"chunk-RNUG3EFC.js","sourcesContent":["/**\n * Stealth Address Utilities (Post-Quantum, Hash-Based)\n *\n * Implements stealth addresses using Poseidon hashes with bech32m encoding.\n * No BabyJubJub curve operations — ownership is proven via hash preimage.\n *\n * Address Format (bech32m):\n * 0zk1<version><chainId><ownerHash><viewingHash>\n *\n * Key Flow (self-shield):\n * 1. User derives ownerHash = Poseidon(spendingSecret)\n * 2. Commitment = Poseidon(amount, ownerHash, blinding, origin, token)\n * 3. Encrypt note with key derived from viewingSecret\n *\n * Key Flow (send to others, future):\n * 1. Decode recipient's stealth address (ownerHash, viewingHash)\n * 2. Generate per-note secret and derive ownerHash for the note\n * 3. Encrypt note so recipient's viewingSecret can decrypt\n */\n\nimport { bech32m } from 'bech32'\nimport {\n randomFieldElement,\n bigintToBytes,\n bytesToBigint,\n} from '../utils/crypto.js'\nimport type { MasterKeys, StarkMasterKeys, OneTimeKeys } from '../keys/types.js'\nimport type { M31Digest } from '../utils/keccak-m31.js'\n\n/**\n * Stealth address prefix\n */\nexport const STEALTH_ADDRESS_PREFIX = '0zk'\n\n/**\n * Address version (v2 = hash-based, post-quantum)\n */\nexport const ADDRESS_VERSION = 2\n\n/**\n * Maximum length for bech32m encoding\n */\nconst BECH32M_LIMIT = 1023\n\n/**\n * Encode a stealth address in bech32m format\n *\n * Format: 0zk1<version><chainId><ownerHash><viewingHash>\n *\n * @param ownerHash - Owner hash = Poseidon(spendingSecret)\n * @param viewingHash - Viewing hash = Poseidon(viewingSecret)\n * @param chainId - Optional chain ID (0 = any chain)\n * @returns bech32m encoded stealth address\n */\nexport function encodeStealthAddress(\n ownerHash: bigint,\n viewingHash: bigint,\n chainId: number = 0\n): string {\n // Build data buffer: version (1 byte) + chainId (4 bytes) + 2 * 32 bytes = 69 bytes\n const data = new Uint8Array(1 + 4 + 32 * 2)\n let offset = 0\n\n // Version\n data[offset++] = ADDRESS_VERSION\n\n // Chain ID (4 bytes, big-endian)\n data[offset++] = (chainId >> 24) & 0xff\n data[offset++] = (chainId >> 16) & 0xff\n data[offset++] = (chainId >> 8) & 0xff\n data[offset++] = chainId & 0xff\n\n // Owner hash (32 bytes)\n const ownerBytes = bigintToBytes(ownerHash, 32)\n data.set(ownerBytes, offset)\n offset += 32\n\n // Viewing hash (32 bytes)\n const viewingBytes = bigintToBytes(viewingHash, 32)\n data.set(viewingBytes, offset)\n\n // Convert to 5-bit words for bech32m\n const words = bech32m.toWords(data)\n\n // Encode with prefix\n return bech32m.encode(STEALTH_ADDRESS_PREFIX, words, BECH32M_LIMIT)\n}\n\n/**\n * Decode a bech32m stealth address\n *\n * @param address - bech32m encoded stealth address\n * @returns Decoded hash values\n */\nexport function decodeStealthAddress(address: string): {\n version: number\n chainId: number\n ownerHash: bigint\n viewingHash: bigint\n} {\n // Decode bech32m\n const decoded = bech32m.decode(address, BECH32M_LIMIT)\n\n // Verify prefix\n if (decoded.prefix !== STEALTH_ADDRESS_PREFIX) {\n throw new Error(`Invalid stealth address prefix: expected '${STEALTH_ADDRESS_PREFIX}', got '${decoded.prefix}'`)\n }\n\n // Convert from 5-bit words back to bytes\n const data = new Uint8Array(bech32m.fromWords(decoded.words))\n\n // Parse version\n let offset = 0\n const version = data[offset++]!\n\n if (version !== ADDRESS_VERSION) {\n throw new Error(`Unsupported address version: ${version}. Expected v${ADDRESS_VERSION} (hash-based).`)\n }\n\n // Parse chain ID\n const chainId =\n (data[offset++]! << 24) |\n (data[offset++]! << 16) |\n (data[offset++]! << 8) |\n data[offset++]!\n\n // Parse owner hash (32 bytes)\n const ownerHash = bytesToBigint(data.slice(offset, offset + 32))\n offset += 32\n\n // Parse viewing hash (32 bytes)\n const viewingHash = bytesToBigint(data.slice(offset, offset + 32))\n\n return {\n version,\n chainId,\n ownerHash,\n viewingHash,\n }\n}\n\n/**\n * Validate a stealth address format\n */\nexport function isValidStealthAddress(address: string): boolean {\n try {\n decodeStealthAddress(address)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Generate stealth address from master keys\n */\nexport function generateStealthAddress(keys: MasterKeys, chainId: number = 0): string {\n return encodeStealthAddress(keys.ownerHash, keys.viewingHash, chainId)\n}\n\n/**\n * Create one-time keys for a transaction (hash-based)\n *\n * For self-shield: the user uses their own spendingSecret directly\n * as the ownerSecret, producing ownerHash = Poseidon(spendingSecret).\n *\n * For sending to others (future): generate a random oneTimeSecret\n * and derive ownerHash = Poseidon(oneTimeSecret).\n *\n * @param recipientOwnerHash - Recipient's owner hash (for verification)\n * @param selfSecret - If self-shield, the user's spending secret\n * @returns One-time keys for the note\n */\nexport async function createOneTimeKeys(\n _recipientOwnerHash?: bigint,\n selfSecret?: bigint,\n): Promise<OneTimeKeys> {\n const { poseidon } = await import('../utils/poseidon.js')\n\n if (selfSecret !== undefined) {\n // Self-shield: use own spending secret\n const ownerHash = await poseidon([selfSecret])\n return {\n oneTimeSecret: selfSecret,\n ownerHash,\n }\n }\n\n // Generate random one-time secret for the note\n const oneTimeSecret = randomFieldElement()\n const ownerHash = await poseidon([oneTimeSecret])\n\n return {\n oneTimeSecret,\n ownerHash,\n }\n}\n\n/**\n * Verify ownership of a note by checking hash preimage\n *\n * @param secret - Claimed spending secret\n * @param expectedOwnerHash - Owner hash from the note commitment\n * @returns True if the secret hashes to the expected owner hash\n */\nexport async function verifyOwnership(\n secret: bigint,\n expectedOwnerHash: bigint\n): Promise<boolean> {\n const { poseidon } = await import('../utils/poseidon.js')\n const computedHash = await poseidon([secret])\n return computedHash === expectedOwnerHash\n}\n\n/**\n * Compute shared secret for note encryption/decryption (hash-based)\n *\n * For self-shield: just uses the viewing secret directly.\n * For sending to others (future): use Poseidon(viewingSecret, recipientViewingHash)\n *\n * @param viewingSecret - Sender's or recipient's viewing secret\n * @param nonce - Optional nonce for key derivation\n * @returns Encryption key as bigint\n */\nexport async function computeNoteEncryptionKey(\n viewingSecret: bigint,\n nonce?: bigint\n): Promise<bigint> {\n const { poseidon } = await import('../utils/poseidon.js')\n if (nonce !== undefined) {\n return poseidon([viewingSecret, nonce])\n }\n return poseidon([viewingSecret])\n}\n\n// =========================================================================\n// STARK Stealth Addresses (0zs prefix, M31/Keccak-based)\n// =========================================================================\n\n/**\n * STARK stealth address prefix\n */\nexport const STARK_STEALTH_ADDRESS_PREFIX = '0zs'\n\n/**\n * STARK address version (v1 = M31/Keccak)\n */\nexport const STARK_ADDRESS_VERSION = 1\n\n/**\n * Encode a STARK stealth address in bech32m format\n *\n * Format: 0zs1<version><chainId><ownerHash[0..3]><viewingHash[0..3]>\n *\n * Each M31 element is encoded as 4 bytes (little-endian).\n * Total data: 1 (version) + 4 (chainId) + 16 (ownerHash) + 16 (viewingHash) = 37 bytes.\n *\n * @param ownerHash - 4 M31 elements: keccak_m31(starkSecret)\n * @param viewingHash - 4 M31 elements: keccak_m31(starkViewingSecret)\n * @param chainId - Optional chain ID (0 = any chain)\n */\nexport function encodeStarkStealthAddress(\n ownerHash: M31Digest,\n viewingHash: M31Digest,\n chainId: number = 0\n): string {\n const data = new Uint8Array(1 + 4 + 16 + 16) // 37 bytes\n let offset = 0\n\n // Version\n data[offset++] = STARK_ADDRESS_VERSION\n\n // Chain ID (4 bytes, big-endian)\n data[offset++] = (chainId >> 24) & 0xff\n data[offset++] = (chainId >> 16) & 0xff\n data[offset++] = (chainId >> 8) & 0xff\n data[offset++] = chainId & 0xff\n\n // Owner hash: 4 M31 elements, each 4 bytes LE\n for (let i = 0; i < 4; i++) {\n const val = Number(ownerHash[i]!)\n data[offset++] = val & 0xff\n data[offset++] = (val >> 8) & 0xff\n data[offset++] = (val >> 16) & 0xff\n data[offset++] = (val >> 24) & 0xff\n }\n\n // Viewing hash: 4 M31 elements, each 4 bytes LE\n for (let i = 0; i < 4; i++) {\n const val = Number(viewingHash[i]!)\n data[offset++] = val & 0xff\n data[offset++] = (val >> 8) & 0xff\n data[offset++] = (val >> 16) & 0xff\n data[offset++] = (val >> 24) & 0xff\n }\n\n const words = bech32m.toWords(data)\n return bech32m.encode(STARK_STEALTH_ADDRESS_PREFIX, words, BECH32M_LIMIT)\n}\n\n/**\n * Decode a STARK stealth address (0zs prefix)\n */\nexport function decodeStarkStealthAddress(address: string): {\n version: number\n chainId: number\n ownerHash: M31Digest\n viewingHash: M31Digest\n} {\n const decoded = bech32m.decode(address, BECH32M_LIMIT)\n\n if (decoded.prefix !== STARK_STEALTH_ADDRESS_PREFIX) {\n throw new Error(\n `Invalid STARK stealth address prefix: expected '${STARK_STEALTH_ADDRESS_PREFIX}', got '${decoded.prefix}'`\n )\n }\n\n const data = new Uint8Array(bech32m.fromWords(decoded.words))\n let offset = 0\n\n const version = data[offset++]!\n if (version !== STARK_ADDRESS_VERSION) {\n throw new Error(\n `Unsupported STARK address version: ${version}. Expected v${STARK_ADDRESS_VERSION}.`\n )\n }\n\n // Chain ID\n const chainId =\n (data[offset++]! << 24) |\n (data[offset++]! << 16) |\n (data[offset++]! << 8) |\n data[offset++]!\n\n // Owner hash: 4 M31 LE uint32s\n const ownerHash: bigint[] = []\n for (let i = 0; i < 4; i++) {\n const val =\n data[offset]! |\n (data[offset + 1]! << 8) |\n (data[offset + 2]! << 16) |\n (data[offset + 3]! << 24)\n ownerHash.push(BigInt(val >>> 0))\n offset += 4\n }\n\n // Viewing hash: 4 M31 LE uint32s\n const viewingHash: bigint[] = []\n for (let i = 0; i < 4; i++) {\n const val =\n data[offset]! |\n (data[offset + 1]! << 8) |\n (data[offset + 2]! << 16) |\n (data[offset + 3]! << 24)\n viewingHash.push(BigInt(val >>> 0))\n offset += 4\n }\n\n return {\n version,\n chainId,\n ownerHash: ownerHash as unknown as M31Digest,\n viewingHash: viewingHash as unknown as M31Digest,\n }\n}\n\n/**\n * Validate a STARK stealth address format\n */\nexport function isValidStarkStealthAddress(address: string): boolean {\n try {\n decodeStarkStealthAddress(address)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Generate a STARK stealth address from STARK master keys\n */\nexport function generateStarkStealthAddress(\n keys: StarkMasterKeys,\n chainId: number = 0\n): string {\n return encodeStarkStealthAddress(keys.starkOwnerHash, keys.starkViewingHash, chainId)\n}\n\n/**\n * Detect whether an address is SNARK (0zk) or STARK (0zs)\n */\nexport function detectAddressType(address: string): 'snark' | 'stark' | 'unknown' {\n if (address.startsWith(STEALTH_ADDRESS_PREFIX + '1')) return 'snark'\n if (address.startsWith(STARK_STEALTH_ADDRESS_PREFIX + '1')) return 'stark'\n return 'unknown'\n}\n","/**\n * Swap Module\n *\n * Core logic for building and interacting with the UPP in-pool swap order book.\n * Framework-agnostic (no React). Reuses withdraw verifier for proofs.\n */\n\nimport { type Address, type Hex, encodeAbiParameters, keccak256, parseAbiParameters, toHex } from 'viem'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Swap order as stored on-chain\n */\nexport interface SwapOrder {\n /** Order ID (= maker's nullifier) */\n orderId: Hex\n /** Token being sold */\n sellToken: Address\n /** Original total sell amount */\n sellAmount: bigint\n /** Remaining sell amount (decremented on each fill) */\n remainingSellAmount: bigint\n /** Token the maker wants to receive */\n buyToken: Address\n /** Price: buyToken per sellToken (1e18 fixed-point) */\n rate: bigint\n /** Accumulated buy token amount from fills */\n accumulatedBuyAmount: bigint\n /** Maker's ASP ID (public, filterable by takers) */\n makerAspId: bigint\n /** Required filler ASP (0 = any) */\n requiredFillerAspId: bigint\n /** Block number after which order expires */\n expiry: bigint\n /** Whether the maker has claimed */\n claimed: boolean\n /** Whether the order was cancelled */\n cancelled: boolean\n}\n\n/**\n * Parameters to place a swap order\n */\nexport interface SwapOrderParams {\n /** Token to sell */\n sellToken: Address\n /** Amount to sell */\n sellAmount: bigint\n /** Token to buy */\n buyToken: Address\n /** Price: buyToken per sellToken (1e18 fixed-point) */\n rate: bigint\n /** Required filler ASP (0n = accept any) */\n requiredFillerAspId?: bigint\n /** Number of blocks until expiry (from current block) */\n expiryBlocks: bigint\n}\n\n/**\n * Parameters to fill a swap order\n */\nexport interface SwapFillParams {\n /** The order to fill */\n orderId: Hex\n /** How much sellToken the filler wants (≤ remaining) */\n takeAmount: bigint\n}\n\n/**\n * Swap order from event log\n */\nexport interface SwapOrderEvent {\n orderId: Hex\n sellToken: Address\n buyToken: Address\n sellAmount: bigint\n rate: bigint\n makerAspId: bigint\n requiredFillerAspId: bigint\n expiry: bigint\n blockNumber: bigint\n /** On-chain remaining sell amount (populated by useSwapOrderBook) */\n remainingSellAmount?: bigint\n /** Whether the order has been claimed */\n claimed?: boolean\n /** Whether the order has been cancelled */\n cancelled?: boolean\n}\n\n/**\n * Swap fill from event log\n */\nexport interface SwapFillEvent {\n orderId: Hex\n fillerNullifier: Hex\n takeAmount: bigint\n giveAmount: bigint\n fillerAspId: bigint\n blockNumber: bigint\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** 1e18 fixed-point precision for swap rates */\nexport const RATE_PRECISION = 10n ** 18n\n\n// ============================================================================\n// Event ABIs (for indexing swap events)\n// ============================================================================\n\nexport const SWAP_ORDER_PLACED_EVENT = {\n type: 'event',\n name: 'SwapOrderPlaced',\n inputs: [\n { name: 'orderId', type: 'bytes32', indexed: true },\n { name: 'sellToken', type: 'address', indexed: true },\n { name: 'buyToken', type: 'address', indexed: true },\n { name: 'sellAmount', type: 'uint256', indexed: false },\n { name: 'rate', type: 'uint256', indexed: false },\n { name: 'makerAspId', type: 'uint256', indexed: false },\n { name: 'requiredFillerAspId', type: 'uint256', indexed: false },\n { name: 'expiry', type: 'uint256', indexed: false },\n ],\n} as const\n\nexport const SWAP_ORDER_FILLED_EVENT = {\n type: 'event',\n name: 'SwapOrderFilled',\n inputs: [\n { name: 'orderId', type: 'bytes32', indexed: true },\n { name: 'fillerNullifier', type: 'bytes32', indexed: true },\n { name: 'takeAmount', type: 'uint256', indexed: false },\n { name: 'giveAmount', type: 'uint256', indexed: false },\n { name: 'fillerAspId', type: 'uint256', indexed: false },\n ],\n} as const\n\nexport const SWAP_ORDER_CLAIMED_EVENT = {\n type: 'event',\n name: 'SwapOrderClaimed',\n inputs: [\n { name: 'orderId', type: 'bytes32', indexed: true },\n { name: 'accumulatedBuyAmount', type: 'uint256', indexed: false },\n { name: 'refundedSellAmount', type: 'uint256', indexed: false },\n ],\n} as const\n\nexport const SWAP_ORDER_CANCELLED_EVENT = {\n type: 'event',\n name: 'SwapOrderCancelled',\n inputs: [\n { name: 'orderId', type: 'bytes32', indexed: true },\n { name: 'refundedSellAmount', type: 'uint256', indexed: false },\n ],\n} as const\n\nexport const SWAP_EVENTS_ABI = [\n SWAP_ORDER_PLACED_EVENT,\n SWAP_ORDER_FILLED_EVENT,\n SWAP_ORDER_CLAIMED_EVENT,\n SWAP_ORDER_CANCELLED_EVENT,\n] as const\n\n// ============================================================================\n// Rate Calculations\n// ============================================================================\n\n/**\n * Compute the giveAmount (buyToken) for a given takeAmount (sellToken) at a rate.\n * giveAmount = (takeAmount * rate) / 1e18\n */\nexport function computeGiveAmount(takeAmount: bigint, rate: bigint): bigint {\n return (takeAmount * rate) / RATE_PRECISION\n}\n\n/**\n * Compute the maximum takeAmount for a given giveAmount and rate.\n * takeAmount = (giveAmount * 1e18) / rate\n */\nexport function computeTakeAmount(giveAmount: bigint, rate: bigint): bigint {\n if (rate === 0n) throw new Error('Rate cannot be zero')\n return (giveAmount * RATE_PRECISION) / rate\n}\n\n/**\n * Compute rate from a desired trade: I want `buyAmount` of buyToken for `sellAmount` of sellToken.\n * rate = (buyAmount * 1e18) / sellAmount\n */\nexport function computeRate(sellAmount: bigint, buyAmount: bigint): bigint {\n if (sellAmount === 0n) throw new Error('Sell amount cannot be zero')\n return (buyAmount * RATE_PRECISION) / sellAmount\n}\n\n/**\n * Format a rate for human display.\n * Returns a string like \"0.0005\" for rate = 500000000000000n (0.0005e18)\n */\nexport function formatRate(rate: bigint, decimals: number = 6): string {\n const whole = rate / RATE_PRECISION\n const frac = rate % RATE_PRECISION\n const fracStr = frac.toString().padStart(18, '0').slice(0, decimals)\n return `${whole}.${fracStr}`\n}\n\n// ============================================================================\n// Cancel Key Management\n// ============================================================================\n\n/**\n * Generate a cancel key hash from a secret.\n * The secret should be a random 32-byte value stored by the maker.\n */\nexport function computeCancelKeyHash(cancelSecret: Hex): Hex {\n return keccak256(encodeAbiParameters(\n parseAbiParameters('bytes32'),\n [cancelSecret]\n ))\n}\n\n/**\n * Generate a random cancel secret.\n */\nexport function generateCancelSecret(): Hex {\n const bytes = new Uint8Array(32)\n crypto.getRandomValues(bytes)\n return toHex(bytes)\n}\n\n// ============================================================================\n// Order Filtering\n// ============================================================================\n\n/**\n * Filter orders by ASP: only show orders from makers on acceptable ASPs.\n */\nexport function filterOrdersByASP(\n orders: SwapOrderEvent[],\n acceptableAspIds: bigint[]\n): SwapOrderEvent[] {\n const aspSet = new Set(acceptableAspIds.map(id => id.toString()))\n return orders.filter(o => aspSet.has(o.makerAspId.toString()))\n}\n\n/**\n * Filter orders by token pair.\n */\nexport function filterOrdersByTokenPair(\n orders: SwapOrderEvent[],\n sellToken: Address,\n buyToken: Address\n): SwapOrderEvent[] {\n const sell = sellToken.toLowerCase()\n const buy = buyToken.toLowerCase()\n return orders.filter(\n o => o.sellToken.toLowerCase() === sell && o.buyToken.toLowerCase() === buy\n )\n}\n\n/**\n * Check if a filler's ASP is accepted by an order.\n */\nexport function isFillerASPAccepted(order: SwapOrder | SwapOrderEvent, fillerAspId: bigint): boolean {\n const required = 'requiredFillerAspId' in order ? order.requiredFillerAspId : 0n\n return required === 0n || required === fillerAspId\n}\n\n// ============================================================================\n// Cancel Secret Persistence (localStorage)\n// ============================================================================\n\nconst CANCEL_SECRET_PREFIX = 'upp_swap_cancel_'\n\nfunction cancelKey(account: string, orderId: Hex): string {\n return `${CANCEL_SECRET_PREFIX}${account.toLowerCase()}_${orderId}`\n}\n\n/**\n * Store a cancel secret in localStorage, scoped by wallet address.\n * Must be called after placing a swap order.\n */\nexport function storeCancelSecret(orderId: Hex, cancelSecret: Hex, account?: string): void {\n if (typeof localStorage === 'undefined') return\n if (account) {\n localStorage.setItem(cancelKey(account, orderId), cancelSecret)\n }\n // Also store unscoped for backward compat\n localStorage.setItem(`${CANCEL_SECRET_PREFIX}${orderId}`, cancelSecret)\n}\n\n/**\n * Retrieve a cancel secret from localStorage.\n * Returns null if not found (e.g. order was placed by someone else).\n */\nexport function getCancelSecret(orderId: Hex, account?: string): Hex | null {\n if (typeof localStorage === 'undefined') return null\n if (account) {\n const scoped = localStorage.getItem(cancelKey(account, orderId))\n if (scoped) return scoped as Hex\n }\n // Fall back to unscoped key\n return localStorage.getItem(`${CANCEL_SECRET_PREFIX}${orderId}`) as Hex | null\n}\n\n/**\n * Remove a cancel secret from localStorage (after claim or cancel).\n */\nexport function removeCancelSecret(orderId: Hex, account?: string): void {\n if (typeof localStorage === 'undefined') return\n if (account) {\n localStorage.removeItem(cancelKey(account, orderId))\n }\n localStorage.removeItem(`${CANCEL_SECRET_PREFIX}${orderId}`)\n}\n\n/**\n * Get all order IDs for a specific wallet address.\n * Falls back to all cancel secrets if no account provided (backward compat).\n */\nexport function getOwnOrderIds(account?: string): Hex[] {\n if (typeof localStorage === 'undefined') return []\n const prefix = account\n ? `${CANCEL_SECRET_PREFIX}${account.toLowerCase()}_`\n : CANCEL_SECRET_PREFIX\n const ids: Hex[] = []\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i)\n if (key?.startsWith(prefix)) {\n ids.push(key.slice(prefix.length) as Hex)\n }\n }\n return ids\n}\n\n// ============================================================================\n// Order Status Helpers\n// ============================================================================\n\n/**\n * Check if an order is still active (not claimed, not cancelled, not expired).\n */\nexport function isOrderActive(order: SwapOrder, currentBlock: bigint): boolean {\n return !order.claimed && !order.cancelled && currentBlock <= order.expiry && order.remainingSellAmount > 0n\n}\n\n/**\n * Compute the total buyToken amount the maker would receive for a full fill.\n */\nexport function computeTotalBuyAmount(sellAmount: bigint, rate: bigint): bigint {\n return computeGiveAmount(sellAmount, rate)\n}\n\n/**\n * Compute fill percentage (0-100) for display.\n */\nexport function computeFillPercentage(order: SwapOrder): number {\n if (order.sellAmount === 0n) return 0\n const filled = order.sellAmount - order.remainingSellAmount\n return Number((filled * 10000n) / order.sellAmount) / 100\n}\n","/**\n * Account Adapter — Pluggable account creation and persistence\n *\n * Abstracts how master keys are derived/loaded/stored.\n * The SDK doesn't care if keys come from a wallet signature,\n * seed phrase, hardware wallet, or external KMS.\n *\n * Persistence is handled via StorageAdapter (IndexedDB, localStorage, etc.)\n */\n\nimport type { MasterKeys, StarkMasterKeys } from '../keys/types.js'\nimport type { StorageAdapter } from '../indexer/types.js'\nimport { toHex } from 'viem'\n\n// ============================================================================\n// Interface\n// ============================================================================\n\n/**\n * Account adapter interface — pluggable key source.\n *\n * Implement this to bring your own key derivation:\n * - StorableAccountAdapter: persists keys via StorageAdapter (built-in)\n * - DirectAccountAdapter: pre-derived keys, no persistence (built-in, for testing)\n * - Custom: seed phrase, hardware wallet, external KMS\n */\nexport interface IAccountAdapter {\n /** Load persisted keys (returns null if no saved account) */\n load(): Promise<{ keys: MasterKeys; starkKeys?: StarkMasterKeys } | null>\n /** Save keys to storage */\n save(keys: MasterKeys, starkKeys?: StarkMasterKeys): Promise<void>\n /** Clear persisted keys */\n clear(): Promise<void>\n}\n\n// ============================================================================\n// Serialization\n// ============================================================================\n\ninterface SerializedAccount {\n version: 3\n spendingSecret: string\n ownerHash: string\n viewingSecret: string\n viewingHash: string\n starkSecret?: string[]\n starkOwnerHash?: string[]\n starkViewingSecret?: string[]\n starkViewingHash?: string[]\n}\n\nfunction serializeAccount(keys: MasterKeys, starkKeys?: StarkMasterKeys): SerializedAccount {\n return {\n version: 3,\n spendingSecret: toHex(keys.spendingSecret, { size: 32 }),\n ownerHash: toHex(keys.ownerHash, { size: 32 }),\n viewingSecret: toHex(keys.viewingSecret, { size: 32 }),\n viewingHash: toHex(keys.viewingHash, { size: 32 }),\n ...(starkKeys ? {\n starkSecret: starkKeys.starkSecret.map(v => v.toString()),\n starkOwnerHash: starkKeys.starkOwnerHash.map(v => v.toString()),\n starkViewingSecret: starkKeys.starkViewingSecret.map(v => v.toString()),\n starkViewingHash: starkKeys.starkViewingHash.map(v => v.toString()),\n } : {}),\n }\n}\n\nfunction deserializeAccount(data: SerializedAccount): { keys: MasterKeys; starkKeys?: StarkMasterKeys } {\n if (data.version !== 3 || !data.spendingSecret) {\n throw new Error('Invalid or outdated account data')\n }\n\n const keys: MasterKeys = {\n spendingSecret: BigInt(data.spendingSecret),\n ownerHash: BigInt(data.ownerHash),\n viewingSecret: BigInt(data.viewingSecret),\n viewingHash: BigInt(data.viewingHash),\n }\n\n let starkKeys: StarkMasterKeys | undefined\n if (data.starkSecret) {\n starkKeys = {\n starkSecret: data.starkSecret.map(s => BigInt(s)) as any,\n starkOwnerHash: data.starkOwnerHash!.map(s => BigInt(s)) as any,\n starkViewingSecret: data.starkViewingSecret!.map(s => BigInt(s)) as any,\n starkViewingHash: data.starkViewingHash!.map(s => BigInt(s)) as any,\n }\n }\n\n return { keys, starkKeys }\n}\n\n// ============================================================================\n// StorableAccountAdapter — persists via StorageAdapter\n// ============================================================================\n\n/**\n * Account adapter that persists keys via a pluggable StorageAdapter.\n *\n * Works with IndexedDB, localStorage, memory, Redis, Postgres — anything\n * that implements StorageAdapter.\n *\n * @example\n * ```ts\n * const storage = createAutoAdapter('upp_account')\n * const adapter = new StorableAccountAdapter(storage, ethAddress)\n * const saved = await adapter.load()\n * if (!saved) {\n * const keys = await deriveKeysFromSignature(sig)\n * await adapter.save(keys, starkKeys)\n * }\n * ```\n */\nexport class StorableAccountAdapter implements IAccountAdapter {\n private storageKey: string\n\n constructor(\n private storage: StorageAdapter,\n ethAddress: string,\n ) {\n this.storageKey = `account_${ethAddress.toLowerCase()}`\n }\n\n async load(): Promise<{ keys: MasterKeys; starkKeys?: StarkMasterKeys } | null> {\n const data = await this.storage.get<SerializedAccount>(this.storageKey)\n if (!data) return null\n try {\n return deserializeAccount(data)\n } catch {\n // Corrupt or outdated — clear it\n await this.storage.delete(this.storageKey)\n return null\n }\n }\n\n async save(keys: MasterKeys, starkKeys?: StarkMasterKeys): Promise<void> {\n const serialized = serializeAccount(keys, starkKeys)\n await this.storage.set(this.storageKey, serialized)\n }\n\n async clear(): Promise<void> {\n await this.storage.delete(this.storageKey)\n }\n}\n\n// ============================================================================\n// DirectAccountAdapter — no persistence (testing, KMS)\n// ============================================================================\n\n/**\n * Direct account adapter — accepts pre-derived keys, no persistence.\n *\n * @example\n * ```ts\n * const adapter = new DirectAccountAdapter(masterKeys, starkKeys)\n * ```\n */\nexport class DirectAccountAdapter implements IAccountAdapter {\n constructor(\n private keys: MasterKeys,\n private starkKeys?: StarkMasterKeys,\n ) {}\n\n async load() {\n return { keys: this.keys, starkKeys: this.starkKeys }\n }\n\n async save(): Promise<void> {\n // No-op — keys are in memory only\n }\n\n async clear(): Promise<void> {\n // No-op\n }\n}\n","/**\n * NoteStore — Single source of truth for note state\n *\n * Framework-agnostic. Uses StorageAdapter for persistence.\n * Handles deduplication, status management, balance calculation.\n *\n * Usage:\n * const store = new NoteStore(createMemoryAdapter())\n * await store.load()\n * store.addNote(note) // returns false if duplicate\n * store.getBalance() // sum of unspent notes\n */\n\nimport type { StorageAdapter } from '../indexer/types.js'\nimport { getAddress } from 'viem'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type NoteStatus = 'pending' | 'confirmed' | 'spent'\nexport type ProofSystem = 'snark' | 'stark'\n\nexport interface ShieldedNote {\n amount: bigint\n blinding: bigint\n commitment: string\n ownerSecret: string\n ownerHash: string\n leafIndex: number\n origin: string\n token: string\n txHash?: string\n status: NoteStatus\n timestamp: number\n proofSystem?: ProofSystem\n}\n\n/** Serialized format for storage (bigints as strings) */\ninterface SerializedNote {\n amount: string\n blinding: string\n commitment: string\n ownerSecret: string\n ownerHash: string\n leafIndex: number\n origin: string\n token: string\n txHash?: string\n status: NoteStatus\n timestamp: number\n proofSystem?: ProofSystem\n}\n\nexport interface INoteStore {\n getNotes(): ShieldedNote[]\n getUnspentNotes(proofSystem?: ProofSystem): ShieldedNote[]\n getBalance(token?: string, proofSystem?: ProofSystem): bigint\n addNote(note: ShieldedNote): boolean\n addNotes(notes: ShieldedNote[]): number\n markSpent(commitment: string): void\n unmarkSpent(commitment: string): void\n updateLeafIndex(commitment: string, leafIndex: number): void\n load(): Promise<void>\n persist(): Promise<void>\n clear(): Promise<void>\n onChange(callback: () => void): () => void\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\nexport class NoteStore implements INoteStore {\n private notes: ShieldedNote[] = []\n private commitmentSet = new Set<string>()\n private listeners = new Set<() => void>()\n private dirty = false\n\n constructor(\n private storage: StorageAdapter,\n private storageKey: string = 'notes',\n ) {}\n\n // ---------- Queries ----------\n\n getNotes(): ShieldedNote[] {\n return [...this.notes]\n }\n\n getUnspentNotes(proofSystem?: ProofSystem): ShieldedNote[] {\n let result = this.notes.filter(n => n.status !== 'spent')\n if (proofSystem) {\n result = result.filter(n => (n.proofSystem ?? 'snark') === proofSystem)\n }\n return result\n }\n\n getBalance(token?: string, proofSystem?: ProofSystem): bigint {\n let notes = this.getUnspentNotes(proofSystem)\n if (token) {\n const normalized = token.toLowerCase()\n notes = notes.filter(n => n.token.toLowerCase() === normalized)\n }\n return notes.reduce((sum, n) => sum + n.amount, 0n)\n }\n\n // ---------- Mutations ----------\n\n /**\n * Add a note. Returns false if duplicate (by commitment).\n * Normalizes token and origin addresses.\n */\n addNote(note: ShieldedNote): boolean {\n const key = note.commitment.toLowerCase()\n if (this.commitmentSet.has(key)) return false\n\n // Normalize addresses\n const normalized: ShieldedNote = {\n ...note,\n commitment: note.commitment.toLowerCase(),\n origin: safeGetAddress(note.origin),\n token: safeGetAddress(note.token),\n }\n\n this.notes.push(normalized)\n this.commitmentSet.add(key)\n this.dirty = true\n this.notify()\n return true\n }\n\n /**\n * Add multiple notes. Returns count of actually added (non-duplicate).\n */\n addNotes(notes: ShieldedNote[]): number {\n let added = 0\n for (const note of notes) {\n if (this.addNote(note)) added++\n }\n return added\n }\n\n /**\n * Mark a note as spent (optimistic — syncNotes reconciles via nullifier check).\n */\n markSpent(commitment: string): void {\n const key = commitment.toLowerCase()\n const note = this.notes.find(n => n.commitment.toLowerCase() === key)\n if (note && note.status !== 'spent') {\n note.status = 'spent'\n this.dirty = true\n this.notify()\n }\n }\n\n /**\n * Un-mark a note as spent (reconciliation: nullifier not found on-chain).\n */\n unmarkSpent(commitment: string): void {\n const key = commitment.toLowerCase()\n const note = this.notes.find(n => n.commitment.toLowerCase() === key)\n if (note && note.status === 'spent') {\n note.status = 'confirmed'\n this.dirty = true\n this.notify()\n }\n }\n\n /**\n * Update the leafIndex for a note (e.g., after confirming on-chain).\n */\n updateLeafIndex(commitment: string, leafIndex: number): void {\n const key = commitment.toLowerCase()\n const note = this.notes.find(n => n.commitment.toLowerCase() === key)\n if (note && note.leafIndex !== leafIndex) {\n note.leafIndex = leafIndex\n this.dirty = true\n this.notify()\n }\n }\n\n // ---------- Persistence ----------\n\n async load(): Promise<void> {\n const serialized = await this.storage.get<SerializedNote[]>(this.storageKey)\n if (!serialized || !Array.isArray(serialized)) {\n this.notes = []\n this.commitmentSet.clear()\n return\n }\n\n // Deduplicate on load — prevents persisted duplicates from propagating\n this.notes = []\n this.commitmentSet.clear()\n let deduped = 0\n for (const s of serialized) {\n const note = deserializeNote(s)\n const key = note.commitment.toLowerCase()\n if (this.commitmentSet.has(key)) { deduped++; continue }\n this.commitmentSet.add(key)\n this.notes.push(note)\n }\n if (deduped > 0) {\n console.log(`[NoteStore] Removed ${deduped} duplicate notes on load`)\n this.dirty = true // will persist the cleaned version\n } else {\n this.dirty = false\n }\n }\n\n async persist(): Promise<void> {\n if (!this.dirty) return\n const serialized = this.notes.map(serializeNote)\n await this.storage.set(this.storageKey, serialized)\n this.dirty = false\n }\n\n async clear(): Promise<void> {\n this.notes = []\n this.commitmentSet.clear()\n this.dirty = false\n await this.storage.delete(this.storageKey)\n this.notify()\n }\n\n // ---------- Events ----------\n\n onChange(callback: () => void): () => void {\n this.listeners.add(callback)\n return () => this.listeners.delete(callback)\n }\n\n private notify(): void {\n for (const listener of this.listeners) {\n listener()\n }\n }\n}\n\n// ============================================================================\n// Serialization\n// ============================================================================\n\nfunction serializeNote(note: ShieldedNote): SerializedNote {\n return {\n ...note,\n amount: note.amount.toString(),\n blinding: note.blinding.toString(),\n }\n}\n\nfunction deserializeNote(s: SerializedNote): ShieldedNote {\n return {\n ...s,\n amount: BigInt(s.amount),\n blinding: BigInt(s.blinding),\n proofSystem: s.proofSystem ?? 'snark',\n }\n}\n\nfunction safeGetAddress(addr: string): string {\n try {\n return getAddress(addr)\n } catch {\n return addr // return as-is if not a valid address (e.g., bigint-encoded origin)\n }\n}\n"]}