@permissionless-technologies/upp-sdk 0.3.6 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/dist/{asp-ZA3RGN7G.js → asp-72WUGTQE.js} +3 -3
  2. package/dist/asp-72WUGTQE.js.map +1 -0
  3. package/dist/{asp-TXSAFFD3.cjs → asp-CUE3NMBN.cjs} +14 -14
  4. package/dist/asp-CUE3NMBN.cjs.map +1 -0
  5. package/dist/{chunk-KXPZUBPI.cjs → chunk-23B5XSS4.cjs} +12 -12
  6. package/dist/{chunk-KXPZUBPI.cjs.map → chunk-23B5XSS4.cjs.map} +1 -1
  7. package/dist/{chunk-SQKBT2SH.cjs → chunk-2G22R7AJ.cjs} +18 -7
  8. package/dist/chunk-2G22R7AJ.cjs.map +1 -0
  9. package/dist/chunk-5QSSX3KR.js +64 -0
  10. package/dist/chunk-5QSSX3KR.js.map +1 -0
  11. package/dist/{chunk-P37MRZ73.js → chunk-6IEYWJVS.js} +8 -8
  12. package/dist/chunk-6IEYWJVS.js.map +1 -0
  13. package/dist/{chunk-5V5HSN6Y.js → chunk-6TFDBBAQ.js} +3 -3
  14. package/dist/{chunk-5V5HSN6Y.js.map → chunk-6TFDBBAQ.js.map} +1 -1
  15. package/dist/{chunk-ZKZV6OI3.cjs → chunk-7BNJV2ZS.cjs} +21 -21
  16. package/dist/{chunk-ZKZV6OI3.cjs.map → chunk-7BNJV2ZS.cjs.map} +1 -1
  17. package/dist/{chunk-XBNYAAMU.js → chunk-7T4CUE6E.js} +3 -3
  18. package/dist/{chunk-XBNYAAMU.js.map → chunk-7T4CUE6E.js.map} +1 -1
  19. package/dist/{chunk-OD2SDC4L.js → chunk-CEJN5ZE5.js} +3 -3
  20. package/dist/{chunk-OD2SDC4L.js.map → chunk-CEJN5ZE5.js.map} +1 -1
  21. package/dist/{chunk-2JQISXBD.js → chunk-DTEAFJG7.js} +8 -8
  22. package/dist/{chunk-2JQISXBD.js.map → chunk-DTEAFJG7.js.map} +1 -1
  23. package/dist/chunk-EHGH6TAW.js +100 -0
  24. package/dist/chunk-EHGH6TAW.js.map +1 -0
  25. package/dist/{chunk-ZU6J7KMY.js → chunk-GPF72JFR.js} +3 -3
  26. package/dist/{chunk-ZU6J7KMY.js.map → chunk-GPF72JFR.js.map} +1 -1
  27. package/dist/chunk-HEHXSV47.cjs +77 -0
  28. package/dist/chunk-HEHXSV47.cjs.map +1 -0
  29. package/dist/chunk-I5EKGD4P.cjs +113 -0
  30. package/dist/chunk-I5EKGD4P.cjs.map +1 -0
  31. package/dist/{chunk-EUP7MBAH.cjs → chunk-IIUKM5VE.cjs} +7 -7
  32. package/dist/{chunk-EUP7MBAH.cjs.map → chunk-IIUKM5VE.cjs.map} +1 -1
  33. package/dist/{chunk-CWSUBAV3.js → chunk-OBBSIPEK.js} +30 -35
  34. package/dist/chunk-OBBSIPEK.js.map +1 -0
  35. package/dist/{chunk-FVT2XRRL.cjs → chunk-Q2E432UK.cjs} +41 -46
  36. package/dist/chunk-Q2E432UK.cjs.map +1 -0
  37. package/dist/{chunk-QKI4QWLT.js → chunk-RNUG3EFC.js} +6 -6
  38. package/dist/{chunk-QKI4QWLT.js.map → chunk-RNUG3EFC.js.map} +1 -1
  39. package/dist/{chunk-3YZSIYJC.cjs → chunk-SWTNJPK5.cjs} +11 -11
  40. package/dist/{chunk-3YZSIYJC.cjs.map → chunk-SWTNJPK5.cjs.map} +1 -1
  41. package/dist/{chunk-BH24DZ5S.cjs → chunk-U3YFYMWF.cjs} +5 -5
  42. package/dist/{chunk-BH24DZ5S.cjs.map → chunk-U3YFYMWF.cjs.map} +1 -1
  43. package/dist/{chunk-3HQ7A6ZM.cjs → chunk-UFEDJJSH.cjs} +5 -5
  44. package/dist/{chunk-3HQ7A6ZM.cjs.map → chunk-UFEDJJSH.cjs.map} +1 -1
  45. package/dist/{chunk-W77GRBO4.js → chunk-UQIM2KT3.js} +3 -3
  46. package/dist/{chunk-W77GRBO4.js.map → chunk-UQIM2KT3.js.map} +1 -1
  47. package/dist/{chunk-SJDPDHSD.cjs → chunk-UTAJSERA.cjs} +4 -4
  48. package/dist/{chunk-SJDPDHSD.cjs.map → chunk-UTAJSERA.cjs.map} +1 -1
  49. package/dist/{chunk-NI62M3W3.cjs → chunk-UYE2JASE.cjs} +2 -2
  50. package/dist/{chunk-NI62M3W3.cjs.map → chunk-UYE2JASE.cjs.map} +1 -1
  51. package/dist/{chunk-S4B7GYLN.js → chunk-W3HLIKC2.js} +18 -8
  52. package/dist/chunk-W3HLIKC2.js.map +1 -0
  53. package/dist/{chunk-NDM5EJEV.cjs → chunk-XVIICZKW.cjs} +7 -7
  54. package/dist/chunk-XVIICZKW.cjs.map +1 -0
  55. package/dist/{chunk-7Q4RSSHM.js → chunk-ZTVXII74.js} +2 -2
  56. package/dist/{chunk-7Q4RSSHM.js.map → chunk-ZTVXII74.js.map} +1 -1
  57. package/dist/core/index.cjs +85 -85
  58. package/dist/core/index.d.cts +2 -2
  59. package/dist/core/index.d.ts +2 -2
  60. package/dist/core/index.js +10 -10
  61. package/dist/{index-B45-okum.d.cts → index-BgPdYxFS.d.cts} +18 -18
  62. package/dist/{index-o-Ds3YAq.d.cts → index-CL4vb3ej.d.cts} +1 -1
  63. package/dist/{index-BIcvNMPt.d.ts → index-CtcXgof_.d.ts} +18 -18
  64. package/dist/{index-DwAJBoU7.d.ts → index-D6nvfm59.d.ts} +1 -1
  65. package/dist/index.cjs +265 -266
  66. package/dist/index.cjs.map +1 -1
  67. package/dist/index.d.cts +3 -3
  68. package/dist/index.d.ts +3 -3
  69. package/dist/index.js +29 -30
  70. package/dist/index.js.map +1 -1
  71. package/dist/indexer/index.cjs +6 -6
  72. package/dist/indexer/index.d.cts +5 -5
  73. package/dist/indexer/index.d.ts +5 -5
  74. package/dist/indexer/index.js +1 -1
  75. package/dist/keys/index.cjs +18 -18
  76. package/dist/keys/index.js +4 -4
  77. package/dist/merkle-DZHEOPH3.cjs +30 -0
  78. package/dist/{merkle-HGDC6OB4.cjs.map → merkle-DZHEOPH3.cjs.map} +1 -1
  79. package/dist/merkle-IF2RMWCF.js +5 -0
  80. package/dist/{merkle-7KS2EHRF.js.map → merkle-IF2RMWCF.js.map} +1 -1
  81. package/dist/poseidon-ACM7E2OH.js +7 -0
  82. package/dist/{poseidon-UHTJLWQM.js.map → poseidon-ACM7E2OH.js.map} +1 -1
  83. package/dist/poseidon-PUSGUIVZ.cjs +61 -0
  84. package/dist/{poseidon-WHJSZSNP.cjs.map → poseidon-PUSGUIVZ.cjs.map} +1 -1
  85. package/dist/proof-JME3IZTX.js +4 -0
  86. package/dist/{proof-C4YBP6RY.js.map → proof-JME3IZTX.js.map} +1 -1
  87. package/dist/proof-XR6XE5PJ.cjs +49 -0
  88. package/dist/{proof-5OECB3RQ.cjs.map → proof-XR6XE5PJ.cjs.map} +1 -1
  89. package/dist/react/index.cjs +47 -51
  90. package/dist/react/index.cjs.map +1 -1
  91. package/dist/react/index.d.cts +2 -2
  92. package/dist/react/index.d.ts +2 -2
  93. package/dist/react/index.js +20 -24
  94. package/dist/react/index.js.map +1 -1
  95. package/dist/{transfer-BzyernBd.d.cts → transfer-D111ihqN.d.cts} +108 -56
  96. package/dist/{transfer-sqS6mJko.d.ts → transfer-DvIXqHCr.d.ts} +108 -56
  97. package/dist/transfer-MQMGSXTH.js +8 -0
  98. package/dist/{transfer-F6YOQTUL.js.map → transfer-MQMGSXTH.js.map} +1 -1
  99. package/dist/transfer-PB6D5VCW.cjs +37 -0
  100. package/dist/{transfer-42C4DXYA.cjs.map → transfer-PB6D5VCW.cjs.map} +1 -1
  101. package/dist/utils/index.cjs +60 -61
  102. package/dist/utils/index.d.cts +37 -14
  103. package/dist/utils/index.d.ts +37 -14
  104. package/dist/utils/index.js +6 -7
  105. package/package.json +4 -2
  106. package/src/contracts/interfaces/IUniversalPrivatePool.sol +10 -8
  107. package/src/contracts/interfaces/IVerifiers.sol +16 -52
  108. package/src/deployments/11155111.json +15 -12
  109. package/dist/asp-TXSAFFD3.cjs.map +0 -1
  110. package/dist/asp-ZA3RGN7G.js.map +0 -1
  111. package/dist/babyjubjub-2MGQVCKB.js +0 -5
  112. package/dist/babyjubjub-2MGQVCKB.js.map +0 -1
  113. package/dist/babyjubjub-MWZLJOVZ.cjs +0 -66
  114. package/dist/babyjubjub-MWZLJOVZ.cjs.map +0 -1
  115. package/dist/chunk-CWSUBAV3.js.map +0 -1
  116. package/dist/chunk-FVT2XRRL.cjs.map +0 -1
  117. package/dist/chunk-JWNXBALH.cjs +0 -57
  118. package/dist/chunk-JWNXBALH.cjs.map +0 -1
  119. package/dist/chunk-NDM5EJEV.cjs.map +0 -1
  120. package/dist/chunk-P37MRZ73.js.map +0 -1
  121. package/dist/chunk-PTDVGWHU.cjs +0 -10
  122. package/dist/chunk-PTDVGWHU.cjs.map +0 -1
  123. package/dist/chunk-S4B7GYLN.js.map +0 -1
  124. package/dist/chunk-SQKBT2SH.cjs.map +0 -1
  125. package/dist/chunk-TSF6HEVS.cjs +0 -201
  126. package/dist/chunk-TSF6HEVS.cjs.map +0 -1
  127. package/dist/chunk-UAVWYXDN.js +0 -8
  128. package/dist/chunk-UAVWYXDN.js.map +0 -1
  129. package/dist/chunk-V23OSL25.js +0 -48
  130. package/dist/chunk-V23OSL25.js.map +0 -1
  131. package/dist/chunk-YOWDERVC.js +0 -186
  132. package/dist/chunk-YOWDERVC.js.map +0 -1
  133. package/dist/merkle-7KS2EHRF.js +0 -5
  134. package/dist/merkle-HGDC6OB4.cjs +0 -30
  135. package/dist/poseidon-UHTJLWQM.js +0 -7
  136. package/dist/poseidon-WHJSZSNP.cjs +0 -45
  137. package/dist/proof-5OECB3RQ.cjs +0 -45
  138. package/dist/proof-C4YBP6RY.js +0 -4
  139. package/dist/transfer-42C4DXYA.cjs +0 -37
  140. package/dist/transfer-F6YOQTUL.js +0 -8
@@ -1,4 +1,4 @@
1
- import { bigintToBytes, bytesToBigint, randomFieldElement, init_crypto } from './chunk-W77GRBO4.js';
1
+ import { bigintToBytes, bytesToBigint, randomFieldElement, init_crypto } from './chunk-UQIM2KT3.js';
2
2
  import { __export, __esm } from './chunk-Z6ZWNWWR.js';
3
3
  import { bech32m } from 'bech32';
4
4
  import { keccak256, encodeAbiParameters, parseAbiParameters, toHex, getAddress } from 'viem';
@@ -73,7 +73,7 @@ function generateStealthAddress(keys, chainId = 0) {
73
73
  return encodeStealthAddress(keys.ownerHash, keys.viewingHash, chainId);
74
74
  }
75
75
  async function createOneTimeKeys(_recipientOwnerHash, selfSecret) {
76
- const { poseidon } = await import('./poseidon-UHTJLWQM.js');
76
+ const { poseidon } = await import('./poseidon-ACM7E2OH.js');
77
77
  if (selfSecret !== void 0) {
78
78
  const ownerHash2 = await poseidon([selfSecret]);
79
79
  return {
@@ -89,12 +89,12 @@ async function createOneTimeKeys(_recipientOwnerHash, selfSecret) {
89
89
  };
90
90
  }
91
91
  async function verifyOwnership(secret, expectedOwnerHash) {
92
- const { poseidon } = await import('./poseidon-UHTJLWQM.js');
92
+ const { poseidon } = await import('./poseidon-ACM7E2OH.js');
93
93
  const computedHash = await poseidon([secret]);
94
94
  return computedHash === expectedOwnerHash;
95
95
  }
96
96
  async function computeNoteEncryptionKey(viewingSecret, nonce) {
97
- const { poseidon } = await import('./poseidon-UHTJLWQM.js');
97
+ const { poseidon } = await import('./poseidon-ACM7E2OH.js');
98
98
  if (nonce !== void 0) {
99
99
  return poseidon([viewingSecret, nonce]);
100
100
  }
@@ -571,5 +571,5 @@ function safeGetAddress(addr) {
571
571
  }
572
572
 
573
573
  export { ADDRESS_VERSION, DirectAccountAdapter, NoteStore, RATE_PRECISION, STARK_ADDRESS_VERSION, STARK_STEALTH_ADDRESS_PREFIX, STEALTH_ADDRESS_PREFIX, SWAP_EVENTS_ABI, SWAP_ORDER_CANCELLED_EVENT, SWAP_ORDER_CLAIMED_EVENT, SWAP_ORDER_FILLED_EVENT, SWAP_ORDER_PLACED_EVENT, StorableAccountAdapter, computeCancelKeyHash, computeFillPercentage, computeGiveAmount, computeNoteEncryptionKey, computeRate, computeTakeAmount, computeTotalBuyAmount, createOneTimeKeys, decodeStarkStealthAddress, decodeStealthAddress, detectAddressType, encodeStarkStealthAddress, encodeStealthAddress, filterOrdersByASP, filterOrdersByTokenPair, formatRate, generateCancelSecret, generateStarkStealthAddress, generateStealthAddress, getCancelSecret, getOwnOrderIds, init_stealth, isFillerASPAccepted, isOrderActive, isValidStarkStealthAddress, isValidStealthAddress, removeCancelSecret, stealth_exports, storeCancelSecret, verifyOwnership };
574
- //# sourceMappingURL=chunk-QKI4QWLT.js.map
575
- //# sourceMappingURL=chunk-QKI4QWLT.js.map
574
+ //# sourceMappingURL=chunk-RNUG3EFC.js.map
575
+ //# sourceMappingURL=chunk-RNUG3EFC.js.map
@@ -1 +1 @@
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":";;;;;;AAAA,IAAA,eAAA,GAAA;AAAA,QAAA,CAAA,eAAA,EAAA;AAAA,EAAA,eAAA,EAAA,MAAA,eAAA;AAAA,EAAA,qBAAA,EAAA,MAAA,qBAAA;AAAA,EAAA,4BAAA,EAAA,MAAA,4BAAA;AAAA,EAAA,sBAAA,EAAA,MAAA,sBAAA;AAAA,EAAA,wBAAA,EAAA,MAAA,wBAAA;AAAA,EAAA,iBAAA,EAAA,MAAA,iBAAA;AAAA,EAAA,yBAAA,EAAA,MAAA,yBAAA;AAAA,EAAA,oBAAA,EAAA,MAAA,oBAAA;AAAA,EAAA,iBAAA,EAAA,MAAA,iBAAA;AAAA,EAAA,yBAAA,EAAA,MAAA,yBAAA;AAAA,EAAA,oBAAA,EAAA,MAAA,oBAAA;AAAA,EAAA,2BAAA,EAAA,MAAA,2BAAA;AAAA,EAAA,sBAAA,EAAA,MAAA,sBAAA;AAAA,EAAA,0BAAA,EAAA,MAAA,0BAAA;AAAA,EAAA,qBAAA,EAAA,MAAA,qBAAA;AAAA,EAAA,eAAA,EAAA,MAAA;AAAA,CAAA,CAAA;AAsDO,SAAS,oBAAA,CACd,SAAA,EACA,WAAA,EACA,OAAA,GAAkB,CAAA,EACV;AAER,EAAA,MAAM,OAAO,IAAI,UAAA,CAAW,CAAA,GAAI,CAAA,GAAI,KAAK,CAAC,CAAA;AAC1C,EAAA,IAAI,MAAA,GAAS,CAAA;AAGb,EAAA,IAAA,CAAK,QAAQ,CAAA,GAAI,eAAA;AAGjB,EAAA,IAAA,CAAK,MAAA,EAAQ,CAAA,GAAK,OAAA,IAAW,EAAA,GAAM,GAAA;AACnC,EAAA,IAAA,CAAK,MAAA,EAAQ,CAAA,GAAK,OAAA,IAAW,EAAA,GAAM,GAAA;AACnC,EAAA,IAAA,CAAK,MAAA,EAAQ,CAAA,GAAK,OAAA,IAAW,CAAA,GAAK,GAAA;AAClC,EAAA,IAAA,CAAK,MAAA,EAAQ,IAAI,OAAA,GAAU,GAAA;AAG3B,EAAA,MAAM,UAAA,GAAa,aAAA,CAAc,SAAA,EAAW,EAAE,CAAA;AAC9C,EAAA,IAAA,CAAK,GAAA,CAAI,YAAY,MAAM,CAAA;AAC3B,EAAA,MAAA,IAAU,EAAA;AAGV,EAAA,MAAM,YAAA,GAAe,aAAA,CAAc,WAAA,EAAa,EAAE,CAAA;AAClD,EAAA,IAAA,CAAK,GAAA,CAAI,cAAc,MAAM,CAAA;AAG7B,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,OAAA,CAAQ,IAAI,CAAA;AAGlC,EAAA,OAAO,OAAA,CAAQ,MAAA,CAAO,sBAAA,EAAwB,KAAA,EAAO,aAAa,CAAA;AACpE;AAQO,SAAS,qBAAqB,OAAA,EAKnC;AAEA,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,MAAA,CAAO,OAAA,EAAS,aAAa,CAAA;AAGrD,EAAA,IAAI,OAAA,CAAQ,WAAW,sBAAA,EAAwB;AAC7C,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,0CAAA,EAA6C,sBAAsB,CAAA,QAAA,EAAW,OAAA,CAAQ,MAAM,CAAA,CAAA,CAAG,CAAA;AAAA,EACjH;AAGA,EAAA,MAAM,OAAO,IAAI,UAAA,CAAW,QAAQ,SAAA,CAAU,OAAA,CAAQ,KAAK,CAAC,CAAA;AAG5D,EAAA,IAAI,MAAA,GAAS,CAAA;AACb,EAAA,MAAM,OAAA,GAAU,KAAK,MAAA,EAAQ,CAAA;AAE7B,EAAA,IAAI,YAAY,eAAA,EAAiB;AAC/B,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,6BAAA,EAAgC,OAAO,CAAA,YAAA,EAAe,eAAe,CAAA,cAAA,CAAgB,CAAA;AAAA,EACvG;AAGA,EAAA,MAAM,OAAA,GACH,IAAA,CAAK,MAAA,EAAQ,CAAA,IAAM,KACnB,IAAA,CAAK,MAAA,EAAQ,CAAA,IAAM,EAAA,GACnB,IAAA,CAAK,MAAA,EAAQ,CAAA,IAAM,CAAA,GACpB,KAAK,MAAA,EAAQ,CAAA;AAGf,EAAA,MAAM,YAAY,aAAA,CAAc,IAAA,CAAK,MAAM,MAAA,EAAQ,MAAA,GAAS,EAAE,CAAC,CAAA;AAC/D,EAAA,MAAA,IAAU,EAAA;AAGV,EAAA,MAAM,cAAc,aAAA,CAAc,IAAA,CAAK,MAAM,MAAA,EAAQ,MAAA,GAAS,EAAE,CAAC,CAAA;AAEjE,EAAA,OAAO;AAAA,IACL,OAAA;AAAA,IACA,OAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACF;AACF;AAKO,SAAS,sBAAsB,OAAA,EAA0B;AAC9D,EAAA,IAAI;AACF,IAAA,oBAAA,CAAqB,OAAO,CAAA;AAC5B,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAKO,SAAS,sBAAA,CAAuB,IAAA,EAAkB,OAAA,GAAkB,CAAA,EAAW;AACpF,EAAA,OAAO,oBAAA,CAAqB,IAAA,CAAK,SAAA,EAAW,IAAA,CAAK,aAAa,OAAO,CAAA;AACvE;AAeA,eAAsB,iBAAA,CACpB,qBACA,UAAA,EACsB;AACtB,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,MAAM,OAAO,wBAAsB,CAAA;AAExD,EAAA,IAAI,eAAe,MAAA,EAAW;AAE5B,IAAA,MAAMA,UAAAA,GAAY,MAAM,QAAA,CAAS,CAAC,UAAU,CAAC,CAAA;AAC7C,IAAA,OAAO;AAAA,MACL,aAAA,EAAe,UAAA;AAAA,MACf,SAAA,EAAAA;AAAA,KACF;AAAA,EACF;AAGA,EAAA,MAAM,gBAAgB,kBAAA,EAAmB;AACzC,EAAA,MAAM,SAAA,GAAY,MAAM,QAAA,CAAS,CAAC,aAAa,CAAC,CAAA;AAEhD,EAAA,OAAO;AAAA,IACL,aAAA;AAAA,IACA;AAAA,GACF;AACF;AASA,eAAsB,eAAA,CACpB,QACA,iBAAA,EACkB;AAClB,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,MAAM,OAAO,wBAAsB,CAAA;AACxD,EAAA,MAAM,YAAA,GAAe,MAAM,QAAA,CAAS,CAAC,MAAM,CAAC,CAAA;AAC5C,EAAA,OAAO,YAAA,KAAiB,iBAAA;AAC1B;AAYA,eAAsB,wBAAA,CACpB,eACA,KAAA,EACiB;AACjB,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,MAAM,OAAO,wBAAsB,CAAA;AACxD,EAAA,IAAI,UAAU,MAAA,EAAW;AACvB,IAAA,OAAO,QAAA,CAAS,CAAC,aAAA,EAAe,KAAK,CAAC,CAAA;AAAA,EACxC;AACA,EAAA,OAAO,QAAA,CAAS,CAAC,aAAa,CAAC,CAAA;AACjC;AA4BO,SAAS,yBAAA,CACd,SAAA,EACA,WAAA,EACA,OAAA,GAAkB,CAAA,EACV;AACR,EAAA,MAAM,OAAO,IAAI,UAAA,CAAW,CAAA,GAAI,CAAA,GAAI,KAAK,EAAE,CAAA;AAC3C,EAAA,IAAI,MAAA,GAAS,CAAA;AAGb,EAAA,IAAA,CAAK,QAAQ,CAAA,GAAI,qBAAA;AAGjB,EAAA,IAAA,CAAK,MAAA,EAAQ,CAAA,GAAK,OAAA,IAAW,EAAA,GAAM,GAAA;AACnC,EAAA,IAAA,CAAK,MAAA,EAAQ,CAAA,GAAK,OAAA,IAAW,EAAA,GAAM,GAAA;AACnC,EAAA,IAAA,CAAK,MAAA,EAAQ,CAAA,GAAK,OAAA,IAAW,CAAA,GAAK,GAAA;AAClC,EAAA,IAAA,CAAK,MAAA,EAAQ,IAAI,OAAA,GAAU,GAAA;AAG3B,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,SAAA,CAAU,CAAC,CAAE,CAAA;AAChC,IAAA,IAAA,CAAK,MAAA,EAAQ,IAAI,GAAA,GAAM,GAAA;AACvB,IAAA,IAAA,CAAK,MAAA,EAAQ,CAAA,GAAK,GAAA,IAAO,CAAA,GAAK,GAAA;AAC9B,IAAA,IAAA,CAAK,MAAA,EAAQ,CAAA,GAAK,GAAA,IAAO,EAAA,GAAM,GAAA;AAC/B,IAAA,IAAA,CAAK,MAAA,EAAQ,CAAA,GAAK,GAAA,IAAO,EAAA,GAAM,GAAA;AAAA,EACjC;AAGA,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,WAAA,CAAY,CAAC,CAAE,CAAA;AAClC,IAAA,IAAA,CAAK,MAAA,EAAQ,IAAI,GAAA,GAAM,GAAA;AACvB,IAAA,IAAA,CAAK,MAAA,EAAQ,CAAA,GAAK,GAAA,IAAO,CAAA,GAAK,GAAA;AAC9B,IAAA,IAAA,CAAK,MAAA,EAAQ,CAAA,GAAK,GAAA,IAAO,EAAA,GAAM,GAAA;AAC/B,IAAA,IAAA,CAAK,MAAA,EAAQ,CAAA,GAAK,GAAA,IAAO,EAAA,GAAM,GAAA;AAAA,EACjC;AAEA,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,OAAA,CAAQ,IAAI,CAAA;AAClC,EAAA,OAAO,OAAA,CAAQ,MAAA,CAAO,4BAAA,EAA8B,KAAA,EAAO,aAAa,CAAA;AAC1E;AAKO,SAAS,0BAA0B,OAAA,EAKxC;AACA,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,MAAA,CAAO,OAAA,EAAS,aAAa,CAAA;AAErD,EAAA,IAAI,OAAA,CAAQ,WAAW,4BAAA,EAA8B;AACnD,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,gDAAA,EAAmD,4BAA4B,CAAA,QAAA,EAAW,OAAA,CAAQ,MAAM,CAAA,CAAA;AAAA,KAC1G;AAAA,EACF;AAEA,EAAA,MAAM,OAAO,IAAI,UAAA,CAAW,QAAQ,SAAA,CAAU,OAAA,CAAQ,KAAK,CAAC,CAAA;AAC5D,EAAA,IAAI,MAAA,GAAS,CAAA;AAEb,EAAA,MAAM,OAAA,GAAU,KAAK,MAAA,EAAQ,CAAA;AAC7B,EAAA,IAAI,YAAY,qBAAA,EAAuB;AACrC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,mCAAA,EAAsC,OAAO,CAAA,YAAA,EAAe,qBAAqB,CAAA,CAAA;AAAA,KACnF;AAAA,EACF;AAGA,EAAA,MAAM,OAAA,GACH,IAAA,CAAK,MAAA,EAAQ,CAAA,IAAM,KACnB,IAAA,CAAK,MAAA,EAAQ,CAAA,IAAM,EAAA,GACnB,IAAA,CAAK,MAAA,EAAQ,CAAA,IAAM,CAAA,GACpB,KAAK,MAAA,EAAQ,CAAA;AAGf,EAAA,MAAM,YAAsB,EAAC;AAC7B,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,IAAA,MAAM,MACJ,IAAA,CAAK,MAAM,CAAA,GACV,IAAA,CAAK,SAAS,CAAC,CAAA,IAAM,CAAA,GACrB,IAAA,CAAK,SAAS,CAAC,CAAA,IAAM,KACrB,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA,IAAM,EAAA;AACxB,IAAA,SAAA,CAAU,IAAA,CAAK,MAAA,CAAO,GAAA,KAAQ,CAAC,CAAC,CAAA;AAChC,IAAA,MAAA,IAAU,CAAA;AAAA,EACZ;AAGA,EAAA,MAAM,cAAwB,EAAC;AAC/B,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,IAAA,MAAM,MACJ,IAAA,CAAK,MAAM,CAAA,GACV,IAAA,CAAK,SAAS,CAAC,CAAA,IAAM,CAAA,GACrB,IAAA,CAAK,SAAS,CAAC,CAAA,IAAM,KACrB,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA,IAAM,EAAA;AACxB,IAAA,WAAA,CAAY,IAAA,CAAK,MAAA,CAAO,GAAA,KAAQ,CAAC,CAAC,CAAA;AAClC,IAAA,MAAA,IAAU,CAAA;AAAA,EACZ;AAEA,EAAA,OAAO;AAAA,IACL,OAAA;AAAA,IACA,OAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACF;AACF;AAKO,SAAS,2BAA2B,OAAA,EAA0B;AACnE,EAAA,IAAI;AACF,IAAA,yBAAA,CAA0B,OAAO,CAAA;AACjC,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAKO,SAAS,2BAAA,CACd,IAAA,EACA,OAAA,GAAkB,CAAA,EACV;AACR,EAAA,OAAO,yBAAA,CAA0B,IAAA,CAAK,cAAA,EAAgB,IAAA,CAAK,kBAAkB,OAAO,CAAA;AACtF;AAKO,SAAS,kBAAkB,OAAA,EAAgD;AAChF,EAAA,IAAI,OAAA,CAAQ,UAAA,CAAW,sBAAA,GAAyB,GAAG,GAAG,OAAO,OAAA;AAC7D,EAAA,IAAI,OAAA,CAAQ,UAAA,CAAW,4BAAA,GAA+B,GAAG,GAAG,OAAO,OAAA;AACnE,EAAA,OAAO,SAAA;AACT;AA3YA,IAgCa,sBAAA,CAAA,CAKA,eAAA,CAAA,CAKP,aAAA,CAAA,CAwMO,4BAAA,CAAA,CAKA;AAvPb,IAAA,YAAA,GAAA,KAAA,CAAA;AAAA,EAAA,qBAAA,GAAA;AAqBA,IAAA,WAAA,EAAA;AAWO,IAAM,sBAAA,GAAyB,KAAA;AAK/B,IAAM,eAAA,GAAkB,CAAA;AAK/B,IAAM,aAAA,GAAgB,IAAA;AAwMf,IAAM,4BAAA,GAA+B,KAAA;AAKrC,IAAM,qBAAA,GAAwB,CAAA;AAAA,EAAA;AAAA,CAAA;AC1I9B,IAAM,iBAAiB,GAAA,IAAO;AAM9B,IAAM,uBAAA,GAA0B;AAAA,EACrC,IAAA,EAAM,OAAA;AAAA,EACN,IAAA,EAAM,iBAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,EAAE,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,SAAA,EAAW,SAAS,IAAA,EAAK;AAAA,IAClD,EAAE,IAAA,EAAM,WAAA,EAAa,IAAA,EAAM,SAAA,EAAW,SAAS,IAAA,EAAK;AAAA,IACpD,EAAE,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,SAAA,EAAW,SAAS,IAAA,EAAK;AAAA,IACnD,EAAE,IAAA,EAAM,YAAA,EAAc,IAAA,EAAM,SAAA,EAAW,SAAS,KAAA,EAAM;AAAA,IACtD,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,SAAA,EAAW,SAAS,KAAA,EAAM;AAAA,IAChD,EAAE,IAAA,EAAM,YAAA,EAAc,IAAA,EAAM,SAAA,EAAW,SAAS,KAAA,EAAM;AAAA,IACtD,EAAE,IAAA,EAAM,qBAAA,EAAuB,IAAA,EAAM,SAAA,EAAW,SAAS,KAAA,EAAM;AAAA,IAC/D,EAAE,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM,SAAA,EAAW,SAAS,KAAA;AAAM;AAEtD;AAEO,IAAM,uBAAA,GAA0B;AAAA,EACrC,IAAA,EAAM,OAAA;AAAA,EACN,IAAA,EAAM,iBAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,EAAE,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,SAAA,EAAW,SAAS,IAAA,EAAK;AAAA,IAClD,EAAE,IAAA,EAAM,iBAAA,EAAmB,IAAA,EAAM,SAAA,EAAW,SAAS,IAAA,EAAK;AAAA,IAC1D,EAAE,IAAA,EAAM,YAAA,EAAc,IAAA,EAAM,SAAA,EAAW,SAAS,KAAA,EAAM;AAAA,IACtD,EAAE,IAAA,EAAM,YAAA,EAAc,IAAA,EAAM,SAAA,EAAW,SAAS,KAAA,EAAM;AAAA,IACtD,EAAE,IAAA,EAAM,aAAA,EAAe,IAAA,EAAM,SAAA,EAAW,SAAS,KAAA;AAAM;AAE3D;AAEO,IAAM,wBAAA,GAA2B;AAAA,EACtC,IAAA,EAAM,OAAA;AAAA,EACN,IAAA,EAAM,kBAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,EAAE,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,SAAA,EAAW,SAAS,IAAA,EAAK;AAAA,IAClD,EAAE,IAAA,EAAM,sBAAA,EAAwB,IAAA,EAAM,SAAA,EAAW,SAAS,KAAA,EAAM;AAAA,IAChE,EAAE,IAAA,EAAM,oBAAA,EAAsB,IAAA,EAAM,SAAA,EAAW,SAAS,KAAA;AAAM;AAElE;AAEO,IAAM,0BAAA,GAA6B;AAAA,EACxC,IAAA,EAAM,OAAA;AAAA,EACN,IAAA,EAAM,oBAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,EAAE,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,SAAA,EAAW,SAAS,IAAA,EAAK;AAAA,IAClD,EAAE,IAAA,EAAM,oBAAA,EAAsB,IAAA,EAAM,SAAA,EAAW,SAAS,KAAA;AAAM;AAElE;AAEO,IAAM,eAAA,GAAkB;AAAA,EAC7B,uBAAA;AAAA,EACA,uBAAA;AAAA,EACA,wBAAA;AAAA,EACA;AACF;AAUO,SAAS,iBAAA,CAAkB,YAAoB,IAAA,EAAsB;AAC1E,EAAA,OAAQ,aAAa,IAAA,GAAQ,cAAA;AAC/B;AAMO,SAAS,iBAAA,CAAkB,YAAoB,IAAA,EAAsB;AAC1E,EAAA,IAAI,IAAA,KAAS,EAAA,EAAI,MAAM,IAAI,MAAM,qBAAqB,CAAA;AACtD,EAAA,OAAQ,aAAa,cAAA,GAAkB,IAAA;AACzC;AAMO,SAAS,WAAA,CAAY,YAAoB,SAAA,EAA2B;AACzE,EAAA,IAAI,UAAA,KAAe,EAAA,EAAI,MAAM,IAAI,MAAM,4BAA4B,CAAA;AACnE,EAAA,OAAQ,YAAY,cAAA,GAAkB,UAAA;AACxC;AAMO,SAAS,UAAA,CAAW,IAAA,EAAc,QAAA,GAAmB,CAAA,EAAW;AACrE,EAAA,MAAM,QAAQ,IAAA,GAAO,cAAA;AACrB,EAAA,MAAM,OAAO,IAAA,GAAO,cAAA;AACpB,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,QAAA,EAAS,CAAE,QAAA,CAAS,IAAI,GAAG,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,QAAQ,CAAA;AACnE,EAAA,OAAO,CAAA,EAAG,KAAK,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA;AAC5B;AAUO,SAAS,qBAAqB,YAAA,EAAwB;AAC3D,EAAA,OAAO,SAAA,CAAU,mBAAA;AAAA,IACf,mBAAmB,SAAS,CAAA;AAAA,IAC5B,CAAC,YAAY;AAAA,GACd,CAAA;AACH;AAKO,SAAS,oBAAA,GAA4B;AAC1C,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,EAAE,CAAA;AAC/B,EAAA,MAAA,CAAO,gBAAgB,KAAK,CAAA;AAC5B,EAAA,OAAO,MAAM,KAAK,CAAA;AACpB;AASO,SAAS,iBAAA,CACd,QACA,gBAAA,EACkB;AAClB,EAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,gBAAA,CAAiB,IAAI,CAAA,EAAA,KAAM,EAAA,CAAG,QAAA,EAAU,CAAC,CAAA;AAChE,EAAA,OAAO,MAAA,CAAO,OAAO,CAAA,CAAA,KAAK,MAAA,CAAO,IAAI,CAAA,CAAE,UAAA,CAAW,QAAA,EAAU,CAAC,CAAA;AAC/D;AAKO,SAAS,uBAAA,CACd,MAAA,EACA,SAAA,EACA,QAAA,EACkB;AAClB,EAAA,MAAM,IAAA,GAAO,UAAU,WAAA,EAAY;AACnC,EAAA,MAAM,GAAA,GAAM,SAAS,WAAA,EAAY;AACjC,EAAA,OAAO,MAAA,CAAO,MAAA;AAAA,IACZ,CAAA,CAAA,KAAK,EAAE,SAAA,CAAU,WAAA,OAAkB,IAAA,IAAQ,CAAA,CAAE,QAAA,CAAS,WAAA,EAAY,KAAM;AAAA,GAC1E;AACF;AAKO,SAAS,mBAAA,CAAoB,OAAmC,WAAA,EAA8B;AACnG,EAAA,MAAM,QAAA,GAAW,qBAAA,IAAyB,KAAA,GAAQ,KAAA,CAAM,mBAAA,GAAsB,EAAA;AAC9E,EAAA,OAAO,QAAA,KAAa,MAAM,QAAA,KAAa,WAAA;AACzC;AAMA,IAAM,oBAAA,GAAuB,kBAAA;AAE7B,SAAS,SAAA,CAAU,SAAiB,OAAA,EAAsB;AACxD,EAAA,OAAO,GAAG,oBAAoB,CAAA,EAAG,QAAQ,WAAA,EAAa,IAAI,OAAO,CAAA,CAAA;AACnE;AAMO,SAAS,iBAAA,CAAkB,OAAA,EAAc,YAAA,EAAmB,OAAA,EAAwB;AACzF,EAAA,IAAI,OAAO,iBAAiB,WAAA,EAAa;AACzC,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,YAAA,CAAa,OAAA,CAAQ,SAAA,CAAU,OAAA,EAAS,OAAO,GAAG,YAAY,CAAA;AAAA,EAChE;AAEA,EAAA,YAAA,CAAa,QAAQ,CAAA,EAAG,oBAAoB,CAAA,EAAG,OAAO,IAAI,YAAY,CAAA;AACxE;AAMO,SAAS,eAAA,CAAgB,SAAc,OAAA,EAA8B;AAC1E,EAAA,IAAI,OAAO,YAAA,KAAiB,WAAA,EAAa,OAAO,IAAA;AAChD,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,MAAM,SAAS,YAAA,CAAa,OAAA,CAAQ,SAAA,CAAU,OAAA,EAAS,OAAO,CAAC,CAAA;AAC/D,IAAA,IAAI,QAAQ,OAAO,MAAA;AAAA,EACrB;AAEA,EAAA,OAAO,aAAa,OAAA,CAAQ,CAAA,EAAG,oBAAoB,CAAA,EAAG,OAAO,CAAA,CAAE,CAAA;AACjE;AAKO,SAAS,kBAAA,CAAmB,SAAc,OAAA,EAAwB;AACvE,EAAA,IAAI,OAAO,iBAAiB,WAAA,EAAa;AACzC,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,YAAA,CAAa,UAAA,CAAW,SAAA,CAAU,OAAA,EAAS,OAAO,CAAC,CAAA;AAAA,EACrD;AACA,EAAA,YAAA,CAAa,UAAA,CAAW,CAAA,EAAG,oBAAoB,CAAA,EAAG,OAAO,CAAA,CAAE,CAAA;AAC7D;AAMO,SAAS,eAAe,OAAA,EAAyB;AACtD,EAAA,IAAI,OAAO,YAAA,KAAiB,WAAA,EAAa,OAAO,EAAC;AACjD,EAAA,MAAM,MAAA,GAAS,UACX,CAAA,EAAG,oBAAoB,GAAG,OAAA,CAAQ,WAAA,EAAa,CAAA,CAAA,CAAA,GAC/C,oBAAA;AACJ,EAAA,MAAM,MAAa,EAAC;AACpB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,YAAA,CAAa,QAAQ,CAAA,EAAA,EAAK;AAC5C,IAAA,MAAM,GAAA,GAAM,YAAA,CAAa,GAAA,CAAI,CAAC,CAAA;AAC9B,IAAA,IAAI,GAAA,EAAK,UAAA,CAAW,MAAM,CAAA,EAAG;AAC3B,MAAA,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,KAAA,CAAM,MAAA,CAAO,MAAM,CAAQ,CAAA;AAAA,IAC1C;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AASO,SAAS,aAAA,CAAc,OAAkB,YAAA,EAA+B;AAC7E,EAAA,OAAO,CAAC,KAAA,CAAM,OAAA,IAAW,CAAC,KAAA,CAAM,aAAa,YAAA,IAAgB,KAAA,CAAM,MAAA,IAAU,KAAA,CAAM,mBAAA,GAAsB,EAAA;AAC3G;AAKO,SAAS,qBAAA,CAAsB,YAAoB,IAAA,EAAsB;AAC9E,EAAA,OAAO,iBAAA,CAAkB,YAAY,IAAI,CAAA;AAC3C;AAKO,SAAS,sBAAsB,KAAA,EAA0B;AAC9D,EAAA,IAAI,KAAA,CAAM,UAAA,KAAe,EAAA,EAAI,OAAO,CAAA;AACpC,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,UAAA,GAAa,KAAA,CAAM,mBAAA;AACxC,EAAA,OAAO,MAAA,CAAQ,MAAA,GAAS,MAAA,GAAU,KAAA,CAAM,UAAU,CAAA,GAAI,GAAA;AACxD;ACxTA,SAAS,gBAAA,CAAiB,MAAkB,SAAA,EAAgD;AAC1F,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,CAAA;AAAA,IACT,gBAAgBC,KAAAA,CAAM,IAAA,CAAK,gBAAgB,EAAE,IAAA,EAAM,IAAI,CAAA;AAAA,IACvD,WAAWA,KAAAA,CAAM,IAAA,CAAK,WAAW,EAAE,IAAA,EAAM,IAAI,CAAA;AAAA,IAC7C,eAAeA,KAAAA,CAAM,IAAA,CAAK,eAAe,EAAE,IAAA,EAAM,IAAI,CAAA;AAAA,IACrD,aAAaA,KAAAA,CAAM,IAAA,CAAK,aAAa,EAAE,IAAA,EAAM,IAAI,CAAA;AAAA,IACjD,GAAI,SAAA,GAAY;AAAA,MACd,aAAa,SAAA,CAAU,WAAA,CAAY,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,UAAU,CAAA;AAAA,MACxD,gBAAgB,SAAA,CAAU,cAAA,CAAe,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,UAAU,CAAA;AAAA,MAC9D,oBAAoB,SAAA,CAAU,kBAAA,CAAmB,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,UAAU,CAAA;AAAA,MACtE,kBAAkB,SAAA,CAAU,gBAAA,CAAiB,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,UAAU;AAAA,QAChE;AAAC,GACP;AACF;AAEA,SAAS,mBAAmB,IAAA,EAA4E;AACtG,EAAA,IAAI,IAAA,CAAK,OAAA,KAAY,CAAA,IAAK,CAAC,KAAK,cAAA,EAAgB;AAC9C,IAAA,MAAM,IAAI,MAAM,kCAAkC,CAAA;AAAA,EACpD;AAEA,EAAA,MAAM,IAAA,GAAmB;AAAA,IACvB,cAAA,EAAgB,MAAA,CAAO,IAAA,CAAK,cAAc,CAAA;AAAA,IAC1C,SAAA,EAAW,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA;AAAA,IAChC,aAAA,EAAe,MAAA,CAAO,IAAA,CAAK,aAAa,CAAA;AAAA,IACxC,WAAA,EAAa,MAAA,CAAO,IAAA,CAAK,WAAW;AAAA,GACtC;AAEA,EAAA,IAAI,SAAA;AACJ,EAAA,IAAI,KAAK,WAAA,EAAa;AACpB,IAAA,SAAA,GAAY;AAAA,MACV,aAAa,IAAA,CAAK,WAAA,CAAY,IAAI,CAAA,CAAA,KAAK,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,MAChD,gBAAgB,IAAA,CAAK,cAAA,CAAgB,IAAI,CAAA,CAAA,KAAK,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,MACvD,oBAAoB,IAAA,CAAK,kBAAA,CAAoB,IAAI,CAAA,CAAA,KAAK,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,MAC/D,kBAAkB,IAAA,CAAK,gBAAA,CAAkB,IAAI,CAAA,CAAA,KAAK,MAAA,CAAO,CAAC,CAAC;AAAA,KAC7D;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,MAAM,SAAA,EAAU;AAC3B;AAuBO,IAAM,yBAAN,MAAwD;AAAA,EAG7D,WAAA,CACU,SACR,UAAA,EACA;AAFQ,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAGR,IAAA,IAAA,CAAK,UAAA,GAAa,CAAA,QAAA,EAAW,UAAA,CAAW,WAAA,EAAa,CAAA,CAAA;AAAA,EACvD;AAAA,EAPQ,UAAA;AAAA,EASR,MAAM,IAAA,GAA0E;AAC9E,IAAA,MAAM,OAAO,MAAM,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAuB,KAAK,UAAU,CAAA;AACtE,IAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,IAAA,IAAI;AACF,MAAA,OAAO,mBAAmB,IAAI,CAAA;AAAA,IAChC,CAAA,CAAA,MAAQ;AAEN,MAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,IAAA,CAAK,UAAU,CAAA;AACzC,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,IAAA,CAAK,IAAA,EAAkB,SAAA,EAA4C;AACvE,IAAA,MAAM,UAAA,GAAa,gBAAA,CAAiB,IAAA,EAAM,SAAS,CAAA;AACnD,IAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,YAAY,UAAU,CAAA;AAAA,EACpD;AAAA,EAEA,MAAM,KAAA,GAAuB;AAC3B,IAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,IAAA,CAAK,UAAU,CAAA;AAAA,EAC3C;AACF;AAcO,IAAM,uBAAN,MAAsD;AAAA,EAC3D,WAAA,CACU,MACA,SAAA,EACR;AAFQ,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AACA,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAAA,EACP;AAAA,EAEH,MAAM,IAAA,GAAO;AACX,IAAA,OAAO,EAAE,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,SAAA,EAAW,KAAK,SAAA,EAAU;AAAA,EACtD;AAAA,EAEA,MAAM,IAAA,GAAsB;AAAA,EAE5B;AAAA,EAEA,MAAM,KAAA,GAAuB;AAAA,EAE7B;AACF;ACrGO,IAAM,YAAN,MAAsC;AAAA,EAM3C,WAAA,CACU,OAAA,EACA,UAAA,GAAqB,OAAA,EAC7B;AAFQ,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AACA,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AAAA,EACP;AAAA,EARK,QAAwB,EAAC;AAAA,EACzB,aAAA,uBAAoB,GAAA,EAAY;AAAA,EAChC,SAAA,uBAAgB,GAAA,EAAgB;AAAA,EAChC,KAAA,GAAQ,KAAA;AAAA;AAAA,EAShB,QAAA,GAA2B;AACzB,IAAA,OAAO,CAAC,GAAG,IAAA,CAAK,KAAK,CAAA;AAAA,EACvB;AAAA,EAEA,gBAAgB,WAAA,EAA2C;AACzD,IAAA,IAAI,SAAS,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA,CAAA,KAAK,CAAA,CAAE,WAAW,OAAO,CAAA;AACxD,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,MAAA,GAAS,OAAO,MAAA,CAAO,CAAA,CAAA,KAAA,CAAM,CAAA,CAAE,WAAA,IAAe,aAAa,WAAW,CAAA;AAAA,IACxE;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEA,UAAA,CAAW,OAAgB,WAAA,EAAmC;AAC5D,IAAA,IAAI,KAAA,GAAQ,IAAA,CAAK,eAAA,CAAgB,WAAW,CAAA;AAC5C,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,MAAM,UAAA,GAAa,MAAM,WAAA,EAAY;AACrC,MAAA,KAAA,GAAQ,MAAM,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,KAAA,CAAM,WAAA,OAAkB,UAAU,CAAA;AAAA,IAChE;AACA,IAAA,OAAO,KAAA,CAAM,OAAO,CAAC,GAAA,EAAK,MAAM,GAAA,GAAM,CAAA,CAAE,QAAQ,EAAE,CAAA;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAQ,IAAA,EAA6B;AACnC,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,UAAA,CAAW,WAAA,EAAY;AACxC,IAAA,IAAI,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,GAAG,GAAG,OAAO,KAAA;AAGxC,IAAA,MAAM,UAAA,GAA2B;AAAA,MAC/B,GAAG,IAAA;AAAA,MACH,UAAA,EAAY,IAAA,CAAK,UAAA,CAAW,WAAA,EAAY;AAAA,MACxC,MAAA,EAAQ,cAAA,CAAe,IAAA,CAAK,MAAM,CAAA;AAAA,MAClC,KAAA,EAAO,cAAA,CAAe,IAAA,CAAK,KAAK;AAAA,KAClC;AAEA,IAAA,IAAA,CAAK,KAAA,CAAM,KAAK,UAAU,CAAA;AAC1B,IAAA,IAAA,CAAK,aAAA,CAAc,IAAI,GAAG,CAAA;AAC1B,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AACb,IAAA,IAAA,CAAK,MAAA,EAAO;AACZ,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,KAAA,EAA+B;AACtC,IAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,IAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,MAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,IAAI,CAAA,EAAG,KAAA,EAAA;AAAA,IAC1B;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,UAAA,EAA0B;AAClC,IAAA,MAAM,GAAA,GAAM,WAAW,WAAA,EAAY;AACnC,IAAA,MAAM,IAAA,GAAO,KAAK,KAAA,CAAM,IAAA,CAAK,OAAK,CAAA,CAAE,UAAA,CAAW,WAAA,EAAY,KAAM,GAAG,CAAA;AACpE,IAAA,IAAI,IAAA,IAAQ,IAAA,CAAK,MAAA,KAAW,OAAA,EAAS;AACnC,MAAA,IAAA,CAAK,MAAA,GAAS,OAAA;AACd,MAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AACb,MAAA,IAAA,CAAK,MAAA,EAAO;AAAA,IACd;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,UAAA,EAA0B;AACpC,IAAA,MAAM,GAAA,GAAM,WAAW,WAAA,EAAY;AACnC,IAAA,MAAM,IAAA,GAAO,KAAK,KAAA,CAAM,IAAA,CAAK,OAAK,CAAA,CAAE,UAAA,CAAW,WAAA,EAAY,KAAM,GAAG,CAAA;AACpE,IAAA,IAAI,IAAA,IAAQ,IAAA,CAAK,MAAA,KAAW,OAAA,EAAS;AACnC,MAAA,IAAA,CAAK,MAAA,GAAS,WAAA;AACd,MAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AACb,MAAA,IAAA,CAAK,MAAA,EAAO;AAAA,IACd;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,eAAA,CAAgB,YAAoB,SAAA,EAAyB;AAC3D,IAAA,MAAM,GAAA,GAAM,WAAW,WAAA,EAAY;AACnC,IAAA,MAAM,IAAA,GAAO,KAAK,KAAA,CAAM,IAAA,CAAK,OAAK,CAAA,CAAE,UAAA,CAAW,WAAA,EAAY,KAAM,GAAG,CAAA;AACpE,IAAA,IAAI,IAAA,IAAQ,IAAA,CAAK,SAAA,KAAc,SAAA,EAAW;AACxC,MAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,MAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AACb,MAAA,IAAA,CAAK,MAAA,EAAO;AAAA,IACd;AAAA,EACF;AAAA;AAAA,EAIA,MAAM,IAAA,GAAsB;AAC1B,IAAA,MAAM,aAAa,MAAM,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAsB,KAAK,UAAU,CAAA;AAC3E,IAAA,IAAI,CAAC,UAAA,IAAc,CAAC,KAAA,CAAM,OAAA,CAAQ,UAAU,CAAA,EAAG;AAC7C,MAAA,IAAA,CAAK,QAAQ,EAAC;AACd,MAAA,IAAA,CAAK,cAAc,KAAA,EAAM;AACzB,MAAA;AAAA,IACF;AAGA,IAAA,IAAA,CAAK,QAAQ,EAAC;AACd,IAAA,IAAA,CAAK,cAAc,KAAA,EAAM;AACzB,IAAA,IAAI,OAAA,GAAU,CAAA;AACd,IAAA,KAAA,MAAW,KAAK,UAAA,EAAY;AAC1B,MAAA,MAAM,IAAA,GAAO,gBAAgB,CAAC,CAAA;AAC9B,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,UAAA,CAAW,WAAA,EAAY;AACxC,MAAA,IAAI,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,GAAG,CAAA,EAAG;AAAE,QAAA,OAAA,EAAA;AAAW,QAAA;AAAA,MAAS;AACvD,MAAA,IAAA,CAAK,aAAA,CAAc,IAAI,GAAG,CAAA;AAC1B,MAAA,IAAA,CAAK,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,IACtB;AACA,IAAA,IAAI,UAAU,CAAA,EAAG;AACf,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,oBAAA,EAAuB,OAAO,CAAA,wBAAA,CAA0B,CAAA;AACpE,MAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AAAA,IACf,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AAAA,IACf;AAAA,EACF;AAAA,EAEA,MAAM,OAAA,GAAyB;AAC7B,IAAA,IAAI,CAAC,KAAK,KAAA,EAAO;AACjB,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,aAAa,CAAA;AAC/C,IAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,YAAY,UAAU,CAAA;AAClD,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AAAA,EACf;AAAA,EAEA,MAAM,KAAA,GAAuB;AAC3B,IAAA,IAAA,CAAK,QAAQ,EAAC;AACd,IAAA,IAAA,CAAK,cAAc,KAAA,EAAM;AACzB,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,IAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,IAAA,CAAK,UAAU,CAAA;AACzC,IAAA,IAAA,CAAK,MAAA,EAAO;AAAA,EACd;AAAA;AAAA,EAIA,SAAS,QAAA,EAAkC;AACzC,IAAA,IAAA,CAAK,SAAA,CAAU,IAAI,QAAQ,CAAA;AAC3B,IAAA,OAAO,MAAM,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA;AAAA,EAC7C;AAAA,EAEQ,MAAA,GAAe;AACrB,IAAA,KAAA,MAAW,QAAA,IAAY,KAAK,SAAA,EAAW;AACrC,MAAA,QAAA,EAAS;AAAA,IACX;AAAA,EACF;AACF;AAMA,SAAS,cAAc,IAAA,EAAoC;AACzD,EAAA,OAAO;AAAA,IACL,GAAG,IAAA;AAAA,IACH,MAAA,EAAQ,IAAA,CAAK,MAAA,CAAO,QAAA,EAAS;AAAA,IAC7B,QAAA,EAAU,IAAA,CAAK,QAAA,CAAS,QAAA;AAAS,GACnC;AACF;AAEA,SAAS,gBAAgB,CAAA,EAAiC;AACxD,EAAA,OAAO;AAAA,IACL,GAAG,CAAA;AAAA,IACH,MAAA,EAAQ,MAAA,CAAO,CAAA,CAAE,MAAM,CAAA;AAAA,IACvB,QAAA,EAAU,MAAA,CAAO,CAAA,CAAE,QAAQ,CAAA;AAAA,IAC3B,WAAA,EAAa,EAAE,WAAA,IAAe;AAAA,GAChC;AACF;AAEA,SAAS,eAAe,IAAA,EAAsB;AAC5C,EAAA,IAAI;AACF,IAAA,OAAO,WAAW,IAAI,CAAA;AAAA,EACxB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF","file":"chunk-QKI4QWLT.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"]}
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"]}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkBH24DZ5S_cjs = require('./chunk-BH24DZ5S.cjs');
3
+ var chunkU3YFYMWF_cjs = require('./chunk-U3YFYMWF.cjs');
4
4
  var viem = require('viem');
5
5
 
6
6
  var STARK_AMOUNT_SCALE = 10n ** 15n;
@@ -9,30 +9,30 @@ var STARK_ASP_TREE_DEPTH = 20;
9
9
  function isStarkAligned(amount) {
10
10
  if (amount <= 0n) return false;
11
11
  const scaled = amount / STARK_AMOUNT_SCALE;
12
- return scaled * STARK_AMOUNT_SCALE === amount && scaled < chunkBH24DZ5S_cjs.M31_P;
12
+ return scaled * STARK_AMOUNT_SCALE === amount && scaled < chunkU3YFYMWF_cjs.M31_P;
13
13
  }
14
14
  function scaleAmountForStark(weiAmount) {
15
15
  const scaled = weiAmount / STARK_AMOUNT_SCALE;
16
16
  if (scaled * STARK_AMOUNT_SCALE !== weiAmount) {
17
17
  throw new Error(`Amount ${weiAmount} not aligned to STARK scale (${STARK_AMOUNT_SCALE})`);
18
18
  }
19
- if (scaled >= chunkBH24DZ5S_cjs.M31_P) {
20
- throw new Error(`Scaled amount ${scaled} exceeds M31 max (${chunkBH24DZ5S_cjs.M31_P})`);
19
+ if (scaled >= chunkU3YFYMWF_cjs.M31_P) {
20
+ throw new Error(`Scaled amount ${scaled} exceeds M31 max (${chunkU3YFYMWF_cjs.M31_P})`);
21
21
  }
22
22
  return Number(scaled);
23
23
  }
24
24
  function truncateToM31(value) {
25
- return Number(value % chunkBH24DZ5S_cjs.M31_P);
25
+ return Number(value % chunkU3YFYMWF_cjs.M31_P);
26
26
  }
27
27
  function addressToM31(addr) {
28
- return Number(BigInt(addr) % chunkBH24DZ5S_cjs.M31_P);
28
+ return Number(BigInt(addr) % chunkU3YFYMWF_cjs.M31_P);
29
29
  }
30
30
  function splitSecretToM31Limbs(secret) {
31
31
  const limbs = [];
32
32
  let remaining = secret;
33
- for (let i = 0; i < chunkBH24DZ5S_cjs.SECRET_LIMBS; i++) {
34
- limbs.push(Number(remaining % chunkBH24DZ5S_cjs.M31_P));
35
- remaining = remaining / chunkBH24DZ5S_cjs.M31_P;
33
+ for (let i = 0; i < chunkU3YFYMWF_cjs.SECRET_LIMBS; i++) {
34
+ limbs.push(Number(remaining % chunkU3YFYMWF_cjs.M31_P));
35
+ remaining = remaining / chunkU3YFYMWF_cjs.M31_P;
36
36
  }
37
37
  return limbs;
38
38
  }
@@ -150,5 +150,5 @@ exports.packM31Digest = packM31Digest;
150
150
  exports.scaleAmountForStark = scaleAmountForStark;
151
151
  exports.splitSecretToM31Limbs = splitSecretToM31Limbs;
152
152
  exports.truncateToM31 = truncateToM31;
153
- //# sourceMappingURL=chunk-3YZSIYJC.cjs.map
154
- //# sourceMappingURL=chunk-3YZSIYJC.cjs.map
153
+ //# sourceMappingURL=chunk-SWTNJPK5.cjs.map
154
+ //# sourceMappingURL=chunk-SWTNJPK5.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/stark.ts"],"names":["M31_P","SECRET_LIMBS","keccak256","encodePacked","pad","numberToHex"],"mappings":"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","file":"chunk-3YZSIYJC.cjs","sourcesContent":["/**\n * STARK Utilities — Amount scaling, witness building, Fiat-Shamir\n *\n * These functions must produce identical outputs to the Rust Stwo prover\n * (stwo-prover/src/) and the Solidity verifier.\n *\n * M31 field: p = 2^31 - 1 = 2,147,483,647\n * Amount precision: 0.001 tokens (1e15 wei scale factor)\n */\n\nimport type { Address, Hex } from 'viem'\nimport { keccak256, encodePacked, pad, numberToHex } from 'viem'\nimport { M31_P, SECRET_LIMBS } from './keccak-m31.js'\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Matches Solidity STARK_AMOUNT_SCALE = 1e15 */\nexport const STARK_AMOUNT_SCALE = 10n ** 15n\n\n/** State tree depth (Merkle tree for commitments) */\nexport const STARK_STATE_TREE_DEPTH = 32\n\n/** ASP tree depth */\nexport const STARK_ASP_TREE_DEPTH = 20\n\n// ============================================================================\n// Amount Scaling\n// ============================================================================\n\n/** Check if a wei amount is STARK-scale aligned and fits in M31. */\nexport function isStarkAligned(amount: bigint): boolean {\n if (amount <= 0n) return false\n const scaled = amount / STARK_AMOUNT_SCALE\n return scaled * STARK_AMOUNT_SCALE === amount && scaled < M31_P\n}\n\n/**\n * Scale a wei amount down for the STARK circuit.\n * Precision: 0.001 tokens (1e15 wei). Max: ~2.1M tokens.\n *\n * @returns The scaled amount as a number (fits in M31)\n * @throws If not aligned to STARK_AMOUNT_SCALE or exceeds M31\n */\nexport function scaleAmountForStark(weiAmount: bigint): number {\n const scaled = weiAmount / STARK_AMOUNT_SCALE\n if (scaled * STARK_AMOUNT_SCALE !== weiAmount) {\n throw new Error(`Amount ${weiAmount} not aligned to STARK scale (${STARK_AMOUNT_SCALE})`)\n }\n if (scaled >= M31_P) {\n throw new Error(`Scaled amount ${scaled} exceeds M31 max (${M31_P})`)\n }\n return Number(scaled)\n}\n\n/** Truncate a bigint to fit in M31 (modular reduction). */\nexport function truncateToM31(value: bigint): number {\n return Number(value % M31_P)\n}\n\n// ============================================================================\n// Field Conversions\n// ============================================================================\n\n/** Convert an Ethereum address to an M31 field element (truncated). */\nexport function addressToM31(addr: Address): number {\n return Number(BigInt(addr) % M31_P)\n}\n\n/**\n * Split a 254-bit spending secret into 8 M31 limbs (248 bits of entropy).\n *\n * Each limb holds 31 bits (reduced mod M31_P). The secret is split\n * little-endian: limb[0] = lowest 31 bits, limb[7] = highest bits.\n *\n * This matches the Rust prover's expectation of `[M31; 8]` for owner_secret.\n */\nexport function splitSecretToM31Limbs(secret: bigint): number[] {\n const limbs: number[] = []\n let remaining = secret\n for (let i = 0; i < SECRET_LIMBS; i++) {\n limbs.push(Number(remaining % M31_P))\n remaining = remaining / M31_P\n }\n return limbs\n}\n\n/**\n * Pack an M31 digest (4 M31 elements) into a uint128 for Solidity.\n * Each element occupies 32 bits (little-endian packing).\n */\nexport function packM31Digest(digest: [number, number, number, number]): bigint {\n return BigInt(digest[0])\n | (BigInt(digest[1]) << 32n)\n | (BigInt(digest[2]) << 64n)\n | (BigInt(digest[3]) << 96n)\n}\n\n// ============================================================================\n// Fiat-Shamir Public Input Seeds\n// ============================================================================\n\n/**\n * Compute the Fiat-Shamir public inputs seed for a STARK withdrawal.\n * Must produce the same hash as Solidity and Rust.\n */\nexport function computeWithdrawPublicInputsSeed(params: {\n nullifier: Hex\n stateRoot: bigint\n aspRoot: bigint\n aspId: bigint\n token: Address\n amount: bigint\n recipient: Address\n isRagequit: boolean\n}): Hex {\n return keccak256(\n encodePacked(\n ['bytes32', 'uint256', 'uint256', 'uint256', 'address', 'uint256', 'address', 'bool'],\n [\n params.nullifier,\n params.stateRoot,\n params.aspRoot,\n params.aspId,\n params.token,\n params.amount,\n params.recipient,\n params.isRagequit,\n ],\n ),\n )\n}\n\n/**\n * Compute the Fiat-Shamir public inputs seed for a STARK transfer.\n * Must produce the same hash as Solidity and Rust.\n */\nexport function computeTransferPublicInputsSeed(params: {\n nullifier: Hex\n stateRoot: bigint\n aspRoot: bigint\n token: Address\n outputCommitment1: Hex\n outputCommitment2: Hex\n}): Hex {\n return keccak256(\n encodePacked(\n ['bytes32', 'uint256', 'uint256', 'address', 'bytes32', 'bytes32'],\n [\n params.nullifier,\n params.stateRoot,\n params.aspRoot,\n params.token,\n params.outputCommitment1,\n params.outputCommitment2,\n ],\n ),\n )\n}\n\n// ============================================================================\n// Witness Types\n// ============================================================================\n\n/**\n * Witness inputs for the STARK withdrawal prover.\n * All numeric values are u32 (must fit in M31 field, i.e. < 2^31 - 1).\n * Hex string fields are for Fiat-Shamir seed binding.\n */\nexport interface StarkWithdrawWitness {\n owner_secret: number[]\n input_amount: number\n input_blinding: number\n input_origin: number\n token: number\n leaf_index: number\n state_path_elements: number[]\n state_path_indices: number[]\n asp_path_elements: number[]\n asp_path_indices: number[]\n withdraw_amount: number\n change_amount: number\n change_blinding: number\n recipient: number\n is_ragequit: number\n // Ethereum-native hex values for Fiat-Shamir seed binding\n nullifier_hex: string\n state_root_hex: string\n asp_root_hex: string\n asp_id_hex: string\n token_address_hex: string\n amount_hex: string\n recipient_address_hex: string\n is_ragequit_bool: boolean\n}\n\n/**\n * Witness inputs for the STARK transfer prover (1-in-2-out).\n * All numeric values are u32 (must fit in M31 field).\n */\nexport interface StarkTransferWitness {\n owner_secret: number[]\n input_amount: number\n input_blinding: number\n input_origin: number\n token: number\n leaf_index: number\n state_path_elements: number[]\n state_path_indices: number[]\n asp_path_elements: number[]\n asp_path_indices: number[]\n // Output 1\n output1_amount: number\n output1_owner_hash: [number, number, number, number]\n output1_blinding: number\n output1_origin: number\n // Output 2\n output2_amount: number\n output2_owner_hash: [number, number, number, number]\n output2_blinding: number\n output2_origin: number\n // Ragequit flag\n is_ragequit: number\n // Ethereum-native hex values for Fiat-Shamir seed binding\n nullifier_hex: string\n state_root_hex: string\n asp_root_hex: string\n token_address_hex: string\n output_commitment_1_hex: string\n output_commitment_2_hex: string\n}\n\n// ============================================================================\n// Witness Builders\n// ============================================================================\n\nfunction toBytes32Hex(value: bigint | Hex): string {\n if (typeof value === 'bigint') {\n return pad(numberToHex(value), { size: 32 })\n }\n return value as string\n}\n\nfunction toAddress20Hex(addr: Address): string {\n return addr.toLowerCase()\n}\n\n/**\n * Build a complete STARK withdrawal witness from note data.\n */\nexport function buildStarkWithdrawWitness(params: {\n ownerSecret: number[]\n inputAmount: number\n inputBlinding: number\n inputOrigin: number\n token: number\n leafIndex: number\n withdrawAmount: number\n changeAmount: number\n changeBlinding: number\n recipient: number\n isRagequit: number\n // Full Ethereum values for seed binding\n nullifierHex: Hex\n stateRootBigInt: bigint\n aspRootBigInt: bigint\n aspIdBigInt: bigint\n tokenAddress: Address\n amountWei: bigint\n recipientAddress: Address\n isRagequitBool: boolean\n}): StarkWithdrawWitness {\n return {\n owner_secret: params.ownerSecret,\n input_amount: params.inputAmount,\n input_blinding: params.inputBlinding,\n input_origin: params.inputOrigin,\n token: params.token,\n leaf_index: params.leafIndex,\n state_path_elements: new Array(STARK_STATE_TREE_DEPTH).fill(0),\n state_path_indices: new Array(STARK_STATE_TREE_DEPTH).fill(0),\n asp_path_elements: new Array(STARK_ASP_TREE_DEPTH).fill(0),\n asp_path_indices: new Array(STARK_ASP_TREE_DEPTH).fill(0),\n withdraw_amount: params.withdrawAmount,\n change_amount: params.changeAmount,\n change_blinding: params.changeBlinding,\n recipient: params.recipient,\n is_ragequit: params.isRagequit,\n nullifier_hex: params.nullifierHex,\n state_root_hex: toBytes32Hex(params.stateRootBigInt),\n asp_root_hex: toBytes32Hex(params.aspRootBigInt),\n asp_id_hex: toBytes32Hex(params.aspIdBigInt),\n token_address_hex: toAddress20Hex(params.tokenAddress),\n amount_hex: toBytes32Hex(params.amountWei),\n recipient_address_hex: toAddress20Hex(params.recipientAddress),\n is_ragequit_bool: params.isRagequitBool,\n }\n}\n\n/**\n * Build a complete STARK transfer witness (1-in-2-out).\n */\nexport function buildStarkTransferWitness(params: {\n ownerSecret: number[]\n inputAmount: number\n inputBlinding: number\n inputOrigin: number\n token: number\n leafIndex: number\n output1Amount: number\n output1OwnerHash: [number, number, number, number]\n output1Blinding: number\n output1Origin: number\n output2Amount: number\n output2OwnerHash: [number, number, number, number]\n output2Blinding: number\n output2Origin: number\n isRagequit: number\n // Full Ethereum values for seed binding\n nullifierHex: Hex\n stateRootBigInt: bigint\n aspRootBigInt: bigint\n tokenAddress: Address\n outputCommitment1Hex: Hex\n outputCommitment2Hex: Hex\n}): StarkTransferWitness {\n return {\n owner_secret: params.ownerSecret,\n input_amount: params.inputAmount,\n input_blinding: params.inputBlinding,\n input_origin: params.inputOrigin,\n token: params.token,\n leaf_index: params.leafIndex,\n state_path_elements: new Array(STARK_STATE_TREE_DEPTH).fill(0),\n state_path_indices: new Array(STARK_STATE_TREE_DEPTH).fill(0),\n asp_path_elements: new Array(STARK_ASP_TREE_DEPTH).fill(0),\n asp_path_indices: new Array(STARK_ASP_TREE_DEPTH).fill(0),\n output1_amount: params.output1Amount,\n output1_owner_hash: params.output1OwnerHash,\n output1_blinding: params.output1Blinding,\n output1_origin: params.output1Origin,\n output2_amount: params.output2Amount,\n output2_owner_hash: params.output2OwnerHash,\n output2_blinding: params.output2Blinding,\n output2_origin: params.output2Origin,\n is_ragequit: params.isRagequit,\n nullifier_hex: params.nullifierHex,\n state_root_hex: toBytes32Hex(params.stateRootBigInt),\n asp_root_hex: toBytes32Hex(params.aspRootBigInt),\n token_address_hex: toAddress20Hex(params.tokenAddress),\n output_commitment_1_hex: params.outputCommitment1Hex,\n output_commitment_2_hex: params.outputCommitment2Hex,\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/utils/stark.ts"],"names":["M31_P","SECRET_LIMBS","keccak256","encodePacked","pad","numberToHex"],"mappings":"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","file":"chunk-SWTNJPK5.cjs","sourcesContent":["/**\n * STARK Utilities — Amount scaling, witness building, Fiat-Shamir\n *\n * These functions must produce identical outputs to the Rust Stwo prover\n * (stwo-prover/src/) and the Solidity verifier.\n *\n * M31 field: p = 2^31 - 1 = 2,147,483,647\n * Amount precision: 0.001 tokens (1e15 wei scale factor)\n */\n\nimport type { Address, Hex } from 'viem'\nimport { keccak256, encodePacked, pad, numberToHex } from 'viem'\nimport { M31_P, SECRET_LIMBS } from './keccak-m31.js'\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Matches Solidity STARK_AMOUNT_SCALE = 1e15 */\nexport const STARK_AMOUNT_SCALE = 10n ** 15n\n\n/** State tree depth (Merkle tree for commitments) */\nexport const STARK_STATE_TREE_DEPTH = 32\n\n/** ASP tree depth */\nexport const STARK_ASP_TREE_DEPTH = 20\n\n// ============================================================================\n// Amount Scaling\n// ============================================================================\n\n/** Check if a wei amount is STARK-scale aligned and fits in M31. */\nexport function isStarkAligned(amount: bigint): boolean {\n if (amount <= 0n) return false\n const scaled = amount / STARK_AMOUNT_SCALE\n return scaled * STARK_AMOUNT_SCALE === amount && scaled < M31_P\n}\n\n/**\n * Scale a wei amount down for the STARK circuit.\n * Precision: 0.001 tokens (1e15 wei). Max: ~2.1M tokens.\n *\n * @returns The scaled amount as a number (fits in M31)\n * @throws If not aligned to STARK_AMOUNT_SCALE or exceeds M31\n */\nexport function scaleAmountForStark(weiAmount: bigint): number {\n const scaled = weiAmount / STARK_AMOUNT_SCALE\n if (scaled * STARK_AMOUNT_SCALE !== weiAmount) {\n throw new Error(`Amount ${weiAmount} not aligned to STARK scale (${STARK_AMOUNT_SCALE})`)\n }\n if (scaled >= M31_P) {\n throw new Error(`Scaled amount ${scaled} exceeds M31 max (${M31_P})`)\n }\n return Number(scaled)\n}\n\n/** Truncate a bigint to fit in M31 (modular reduction). */\nexport function truncateToM31(value: bigint): number {\n return Number(value % M31_P)\n}\n\n// ============================================================================\n// Field Conversions\n// ============================================================================\n\n/** Convert an Ethereum address to an M31 field element (truncated). */\nexport function addressToM31(addr: Address): number {\n return Number(BigInt(addr) % M31_P)\n}\n\n/**\n * Split a 254-bit spending secret into 8 M31 limbs (248 bits of entropy).\n *\n * Each limb holds 31 bits (reduced mod M31_P). The secret is split\n * little-endian: limb[0] = lowest 31 bits, limb[7] = highest bits.\n *\n * This matches the Rust prover's expectation of `[M31; 8]` for owner_secret.\n */\nexport function splitSecretToM31Limbs(secret: bigint): number[] {\n const limbs: number[] = []\n let remaining = secret\n for (let i = 0; i < SECRET_LIMBS; i++) {\n limbs.push(Number(remaining % M31_P))\n remaining = remaining / M31_P\n }\n return limbs\n}\n\n/**\n * Pack an M31 digest (4 M31 elements) into a uint128 for Solidity.\n * Each element occupies 32 bits (little-endian packing).\n */\nexport function packM31Digest(digest: [number, number, number, number]): bigint {\n return BigInt(digest[0])\n | (BigInt(digest[1]) << 32n)\n | (BigInt(digest[2]) << 64n)\n | (BigInt(digest[3]) << 96n)\n}\n\n// ============================================================================\n// Fiat-Shamir Public Input Seeds\n// ============================================================================\n\n/**\n * Compute the Fiat-Shamir public inputs seed for a STARK withdrawal.\n * Must produce the same hash as Solidity and Rust.\n */\nexport function computeWithdrawPublicInputsSeed(params: {\n nullifier: Hex\n stateRoot: bigint\n aspRoot: bigint\n aspId: bigint\n token: Address\n amount: bigint\n recipient: Address\n isRagequit: boolean\n}): Hex {\n return keccak256(\n encodePacked(\n ['bytes32', 'uint256', 'uint256', 'uint256', 'address', 'uint256', 'address', 'bool'],\n [\n params.nullifier,\n params.stateRoot,\n params.aspRoot,\n params.aspId,\n params.token,\n params.amount,\n params.recipient,\n params.isRagequit,\n ],\n ),\n )\n}\n\n/**\n * Compute the Fiat-Shamir public inputs seed for a STARK transfer.\n * Must produce the same hash as Solidity and Rust.\n */\nexport function computeTransferPublicInputsSeed(params: {\n nullifier: Hex\n stateRoot: bigint\n aspRoot: bigint\n token: Address\n outputCommitment1: Hex\n outputCommitment2: Hex\n}): Hex {\n return keccak256(\n encodePacked(\n ['bytes32', 'uint256', 'uint256', 'address', 'bytes32', 'bytes32'],\n [\n params.nullifier,\n params.stateRoot,\n params.aspRoot,\n params.token,\n params.outputCommitment1,\n params.outputCommitment2,\n ],\n ),\n )\n}\n\n// ============================================================================\n// Witness Types\n// ============================================================================\n\n/**\n * Witness inputs for the STARK withdrawal prover.\n * All numeric values are u32 (must fit in M31 field, i.e. < 2^31 - 1).\n * Hex string fields are for Fiat-Shamir seed binding.\n */\nexport interface StarkWithdrawWitness {\n owner_secret: number[]\n input_amount: number\n input_blinding: number\n input_origin: number\n token: number\n leaf_index: number\n state_path_elements: number[]\n state_path_indices: number[]\n asp_path_elements: number[]\n asp_path_indices: number[]\n withdraw_amount: number\n change_amount: number\n change_blinding: number\n recipient: number\n is_ragequit: number\n // Ethereum-native hex values for Fiat-Shamir seed binding\n nullifier_hex: string\n state_root_hex: string\n asp_root_hex: string\n asp_id_hex: string\n token_address_hex: string\n amount_hex: string\n recipient_address_hex: string\n is_ragequit_bool: boolean\n}\n\n/**\n * Witness inputs for the STARK transfer prover (1-in-2-out).\n * All numeric values are u32 (must fit in M31 field).\n */\nexport interface StarkTransferWitness {\n owner_secret: number[]\n input_amount: number\n input_blinding: number\n input_origin: number\n token: number\n leaf_index: number\n state_path_elements: number[]\n state_path_indices: number[]\n asp_path_elements: number[]\n asp_path_indices: number[]\n // Output 1\n output1_amount: number\n output1_owner_hash: [number, number, number, number]\n output1_blinding: number\n output1_origin: number\n // Output 2\n output2_amount: number\n output2_owner_hash: [number, number, number, number]\n output2_blinding: number\n output2_origin: number\n // Ragequit flag\n is_ragequit: number\n // Ethereum-native hex values for Fiat-Shamir seed binding\n nullifier_hex: string\n state_root_hex: string\n asp_root_hex: string\n token_address_hex: string\n output_commitment_1_hex: string\n output_commitment_2_hex: string\n}\n\n// ============================================================================\n// Witness Builders\n// ============================================================================\n\nfunction toBytes32Hex(value: bigint | Hex): string {\n if (typeof value === 'bigint') {\n return pad(numberToHex(value), { size: 32 })\n }\n return value as string\n}\n\nfunction toAddress20Hex(addr: Address): string {\n return addr.toLowerCase()\n}\n\n/**\n * Build a complete STARK withdrawal witness from note data.\n */\nexport function buildStarkWithdrawWitness(params: {\n ownerSecret: number[]\n inputAmount: number\n inputBlinding: number\n inputOrigin: number\n token: number\n leafIndex: number\n withdrawAmount: number\n changeAmount: number\n changeBlinding: number\n recipient: number\n isRagequit: number\n // Full Ethereum values for seed binding\n nullifierHex: Hex\n stateRootBigInt: bigint\n aspRootBigInt: bigint\n aspIdBigInt: bigint\n tokenAddress: Address\n amountWei: bigint\n recipientAddress: Address\n isRagequitBool: boolean\n}): StarkWithdrawWitness {\n return {\n owner_secret: params.ownerSecret,\n input_amount: params.inputAmount,\n input_blinding: params.inputBlinding,\n input_origin: params.inputOrigin,\n token: params.token,\n leaf_index: params.leafIndex,\n state_path_elements: new Array(STARK_STATE_TREE_DEPTH).fill(0),\n state_path_indices: new Array(STARK_STATE_TREE_DEPTH).fill(0),\n asp_path_elements: new Array(STARK_ASP_TREE_DEPTH).fill(0),\n asp_path_indices: new Array(STARK_ASP_TREE_DEPTH).fill(0),\n withdraw_amount: params.withdrawAmount,\n change_amount: params.changeAmount,\n change_blinding: params.changeBlinding,\n recipient: params.recipient,\n is_ragequit: params.isRagequit,\n nullifier_hex: params.nullifierHex,\n state_root_hex: toBytes32Hex(params.stateRootBigInt),\n asp_root_hex: toBytes32Hex(params.aspRootBigInt),\n asp_id_hex: toBytes32Hex(params.aspIdBigInt),\n token_address_hex: toAddress20Hex(params.tokenAddress),\n amount_hex: toBytes32Hex(params.amountWei),\n recipient_address_hex: toAddress20Hex(params.recipientAddress),\n is_ragequit_bool: params.isRagequitBool,\n }\n}\n\n/**\n * Build a complete STARK transfer witness (1-in-2-out).\n */\nexport function buildStarkTransferWitness(params: {\n ownerSecret: number[]\n inputAmount: number\n inputBlinding: number\n inputOrigin: number\n token: number\n leafIndex: number\n output1Amount: number\n output1OwnerHash: [number, number, number, number]\n output1Blinding: number\n output1Origin: number\n output2Amount: number\n output2OwnerHash: [number, number, number, number]\n output2Blinding: number\n output2Origin: number\n isRagequit: number\n // Full Ethereum values for seed binding\n nullifierHex: Hex\n stateRootBigInt: bigint\n aspRootBigInt: bigint\n tokenAddress: Address\n outputCommitment1Hex: Hex\n outputCommitment2Hex: Hex\n}): StarkTransferWitness {\n return {\n owner_secret: params.ownerSecret,\n input_amount: params.inputAmount,\n input_blinding: params.inputBlinding,\n input_origin: params.inputOrigin,\n token: params.token,\n leaf_index: params.leafIndex,\n state_path_elements: new Array(STARK_STATE_TREE_DEPTH).fill(0),\n state_path_indices: new Array(STARK_STATE_TREE_DEPTH).fill(0),\n asp_path_elements: new Array(STARK_ASP_TREE_DEPTH).fill(0),\n asp_path_indices: new Array(STARK_ASP_TREE_DEPTH).fill(0),\n output1_amount: params.output1Amount,\n output1_owner_hash: params.output1OwnerHash,\n output1_blinding: params.output1Blinding,\n output1_origin: params.output1Origin,\n output2_amount: params.output2Amount,\n output2_owner_hash: params.output2OwnerHash,\n output2_blinding: params.output2Blinding,\n output2_origin: params.output2Origin,\n is_ragequit: params.isRagequit,\n nullifier_hex: params.nullifierHex,\n state_root_hex: toBytes32Hex(params.stateRootBigInt),\n asp_root_hex: toBytes32Hex(params.aspRootBigInt),\n token_address_hex: toAddress20Hex(params.tokenAddress),\n output_commitment_1_hex: params.outputCommitment1Hex,\n output_commitment_2_hex: params.outputCommitment2Hex,\n }\n}\n"]}
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var chunk3HQ7A6ZM_cjs = require('./chunk-3HQ7A6ZM.cjs');
3
+ var chunkUFEDJJSH_cjs = require('./chunk-UFEDJJSH.cjs');
4
4
  var viem = require('viem');
5
5
 
6
6
  // src/utils/keccak-m31.ts
7
- chunk3HQ7A6ZM_cjs.init_crypto();
7
+ chunkUFEDJJSH_cjs.init_crypto();
8
8
  var M31_P = 2147483647n;
9
9
  var DIGEST_SIZE = 4;
10
10
  var SECRET_LIMBS = 8;
@@ -18,7 +18,7 @@ function keccakM31(inputs) {
18
18
  bytes[offset + 2] = val >> 16 & 255;
19
19
  bytes[offset + 3] = val >> 24 & 255;
20
20
  }
21
- const hashHex = viem.keccak256(chunk3HQ7A6ZM_cjs.bytesToHex(bytes));
21
+ const hashHex = viem.keccak256(chunkUFEDJJSH_cjs.bytesToHex(bytes));
22
22
  return bytesToM31Digest(hashHex);
23
23
  }
24
24
  function keccakHashTwo(left, right) {
@@ -87,5 +87,5 @@ exports.computeStarkOwnerHash = computeStarkOwnerHash;
87
87
  exports.keccakHashTwo = keccakHashTwo;
88
88
  exports.keccakM31 = keccakM31;
89
89
  exports.splitToM31Limbs = splitToM31Limbs;
90
- //# sourceMappingURL=chunk-BH24DZ5S.cjs.map
91
- //# sourceMappingURL=chunk-BH24DZ5S.cjs.map
90
+ //# sourceMappingURL=chunk-U3YFYMWF.cjs.map
91
+ //# sourceMappingURL=chunk-U3YFYMWF.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/keccak-m31.ts"],"names":["init_crypto","keccak256","bytesToHex"],"mappings":";;;;;;AAgBAA,6BAAA,EAAA;AAGO,IAAM,KAAA,GAAQ;AAGd,IAAM,WAAA,GAAc;AAGpB,IAAM,YAAA,GAAe;AAgBrB,SAAS,UAAU,MAAA,EAAsC;AAE9D,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,MAAA,CAAO,SAAS,CAAC,CAAA;AAC9C,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AACtC,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,MAAA,CAAO,CAAC,IAAK,WAAW,CAAA;AAC3C,IAAA,MAAM,SAAS,CAAA,GAAI,CAAA;AACnB,IAAA,KAAA,CAAM,MAAM,IAAI,GAAA,GAAM,GAAA;AACtB,IAAA,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA,GAAK,GAAA,IAAO,CAAA,GAAK,GAAA;AACjC,IAAA,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA,GAAK,GAAA,IAAO,EAAA,GAAM,GAAA;AAClC,IAAA,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA,GAAK,GAAA,IAAO,EAAA,GAAM,GAAA;AAAA,EACpC;AAGA,EAAA,MAAM,OAAA,GAAUC,cAAA,CAAUC,4BAAA,CAAW,KAAK,CAAC,CAAA;AAG3C,EAAA,OAAO,iBAAiB,OAAO,CAAA;AACjC;AAOO,SAAS,aAAA,CAAc,MAAc,KAAA,EAA0B;AACpE,EAAA,OAAO,SAAA,CAAU,CAAC,IAAA,EAAM,KAAK,CAAC,CAAA;AAChC;AAOO,SAAS,sBAAsB,WAAA,EAAmC;AACvE,EAAA,OAAO,UAAU,WAAW,CAAA;AAC9B;AASO,SAAS,sBAAA,CACd,MAAA,EACA,SAAA,EACA,QAAA,EACA,QACA,KAAA,EACW;AACX,EAAA,OAAO,SAAA,CAAU;AAAA,IACf,MAAA;AAAA,IACA,UAAU,CAAC,CAAA;AAAA,IACX,UAAU,CAAC,CAAA;AAAA,IACX,UAAU,CAAC,CAAA;AAAA,IACX,UAAU,CAAC,CAAA;AAAA,IACX,QAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACD,CAAA;AACH;AASO,SAAS,qBAAA,CACd,WAAA,EACA,SAAA,EACA,UAAA,EACW;AACX,EAAA,OAAO,SAAA,CAAU;AAAA,IACf,GAAG,WAAA;AAAA,IACH,SAAA;AAAA,IACA,GAAG;AAAA,GACJ,CAAA;AACH;AAQO,SAAS,gBAAgB,OAAA,EAAmC;AACjE,EAAA,MAAM,KAAA,GAAQ,gBAAgB,OAAO,CAAA;AACrC,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,YAAA,EAAc,CAAA,EAAA,EAAK;AACrC,IAAA,MAAM,SAAS,CAAA,GAAI,CAAA;AACnB,IAAA,MAAM,MAAO,KAAA,CAAM,MAAM,CAAA,GACnB,KAAA,CAAM,SAAS,CAAC,CAAA,IAAO,CAAA,GACvB,KAAA,CAAM,SAAS,CAAC,CAAA,IAAO,KACvB,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA,IAAO,EAAA;AAC7B,IAAA,KAAA,CAAM,IAAA,CAAK,MAAA,CAAO,GAAA,KAAQ,CAAC,IAAI,KAAK,CAAA;AAAA,EACtC;AACA,EAAA,OAAO,KAAA;AACT;AAOA,SAAS,iBAAiB,OAAA,EAAmC;AAC3D,EAAA,MAAM,KAAA,GAAQ,gBAAgB,OAAO,CAAA;AACrC,EAAA,MAAM,SAAmB,EAAC;AAE1B,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,WAAA,EAAa,CAAA,EAAA,EAAK;AACpC,IAAA,MAAM,SAAS,CAAA,GAAI,CAAA;AAEnB,IAAA,IAAI,GAAA,GAAM,EAAA;AACV,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,MAAA,GAAA,IAAO,MAAA,CAAO,MAAM,MAAA,GAAS,CAAC,CAAE,CAAA,IAAK,MAAA,CAAO,IAAI,CAAC,CAAA;AAAA,IACnD;AACA,IAAA,MAAA,CAAO,IAAA,CAAK,MAAM,KAAK,CAAA;AAAA,EACzB;AAEA,EAAA,OAAO,MAAA;AACT;AAKA,SAAS,gBAAgB,GAAA,EAAgC;AACvD,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,KAAA,CAAM,CAAC,CAAA;AACvB,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,GAAA,CAAI,SAAS,CAAC,CAAA;AAC3C,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,KAAA,CAAM,CAAC,CAAA,GAAI,QAAA,CAAS,GAAA,CAAI,KAAA,CAAM,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,GAAI,CAAC,CAAA,EAAG,EAAE,CAAA;AAAA,EACrD;AACA,EAAA,OAAO,KAAA;AACT","file":"chunk-BH24DZ5S.cjs","sourcesContent":["/**\n * Keccak-256 hashing over M31 field elements.\n *\n * This module implements the same hashing algorithm as the Rust Stwo prover\n * (stwo-prover/src/hash.rs), producing identical outputs for identical inputs.\n *\n * Algorithm:\n * 1. Each M31 element is encoded as 4 little-endian bytes\n * 2. All encoded bytes are concatenated and fed to Keccak-256\n * 3. The 32-byte output is split into 4 chunks of 8 bytes\n * 4. Each chunk is read as a little-endian uint64 and reduced mod M31_P\n *\n * M31 field: p = 2^31 - 1 = 2,147,483,647\n */\n\nimport { keccak256 } from 'viem'\nimport { bytesToHex } from './crypto.js'\n\n/** The M31 prime: 2^31 - 1 */\nexport const M31_P = 2147483647n\n\n/** Number of M31 elements in a digest */\nexport const DIGEST_SIZE = 4\n\n/** Number of M31 limbs for owner secrets (248 bits of entropy) */\nexport const SECRET_LIMBS = 8\n\n/** M31 digest type: tuple of 4 M31 values */\nexport type M31Digest = readonly [bigint, bigint, bigint, bigint]\n\n/** M31 secret type: tuple of 8 M31 values */\nexport type M31Secret = readonly [bigint, bigint, bigint, bigint, bigint, bigint, bigint, bigint]\n\n/**\n * Hash arbitrary M31 elements using Keccak-256.\n *\n * Matches Rust: `hash_m31(inputs: &[M31]) -> [M31; 4]`\n *\n * Each M31 is encoded as 4 little-endian bytes. The keccak output\n * is split into 4 × 8-byte LE chunks, each reduced mod M31_P.\n */\nexport function keccakM31(inputs: readonly bigint[]): M31Digest {\n // Encode each M31 as 4 little-endian bytes\n const bytes = new Uint8Array(inputs.length * 4)\n for (let i = 0; i < inputs.length; i++) {\n const val = Number(inputs[i]! & 0xFFFFFFFFn)\n const offset = i * 4\n bytes[offset] = val & 0xFF\n bytes[offset + 1] = (val >> 8) & 0xFF\n bytes[offset + 2] = (val >> 16) & 0xFF\n bytes[offset + 3] = (val >> 24) & 0xFF\n }\n\n // Keccak-256\n const hashHex = keccak256(bytesToHex(bytes))\n\n // Parse 32-byte output into 4 × uint64 LE, reduce mod M31_P\n return bytesToM31Digest(hashHex)\n}\n\n/**\n * Hash two M31 elements (Merkle tree node hash).\n *\n * Matches Rust: `hash_two(left: M31, right: M31) -> [M31; 4]`\n */\nexport function keccakHashTwo(left: bigint, right: bigint): M31Digest {\n return keccakM31([left, right])\n}\n\n/**\n * Compute owner hash from an 8-limb secret.\n *\n * Matches Rust: `compute_owner_hash(owner_secret: &[M31; 8]) -> [M31; 4]`\n */\nexport function computeStarkOwnerHash(ownerSecret: M31Secret): M31Digest {\n return keccakM31(ownerSecret)\n}\n\n/**\n * Compute a STARK note commitment.\n *\n * Matches Rust: `compute_commitment(amount, owner_hash, blinding, origin, token)`\n *\n * Input order: [amount, ownerHash[0], ownerHash[1], ownerHash[2], ownerHash[3], blinding, origin, token]\n */\nexport function computeStarkCommitment(\n amount: bigint,\n ownerHash: M31Digest,\n blinding: bigint,\n origin: bigint,\n token: bigint,\n): M31Digest {\n return keccakM31([\n amount,\n ownerHash[0],\n ownerHash[1],\n ownerHash[2],\n ownerHash[3],\n blinding,\n origin,\n token,\n ])\n}\n\n/**\n * Compute a STARK nullifier.\n *\n * Matches Rust: `compute_nullifier(owner_secret, leaf_index, commitment)`\n *\n * Input order: [ownerSecret[0..8], leafIndex, commitment[0..4]]\n */\nexport function computeStarkNullifier(\n ownerSecret: M31Secret,\n leafIndex: bigint,\n commitment: M31Digest,\n): M31Digest {\n return keccakM31([\n ...ownerSecret,\n leafIndex,\n ...commitment,\n ])\n}\n\n/**\n * Split a 32-byte keccak hash into 8 M31 limbs.\n *\n * Used for deriving STARK spending/viewing secrets from a seed.\n * Each limb is 4 bytes of the hash, read as LE uint32, reduced mod M31_P.\n */\nexport function splitToM31Limbs(hashHex: `0x${string}`): M31Secret {\n const bytes = hexToUint8Array(hashHex)\n const limbs: bigint[] = []\n for (let i = 0; i < SECRET_LIMBS; i++) {\n const offset = i * 4\n const val = (bytes[offset]!)\n | ((bytes[offset + 1]!) << 8)\n | ((bytes[offset + 2]!) << 16)\n | ((bytes[offset + 3]!) << 24)\n limbs.push(BigInt(val >>> 0) % M31_P)\n }\n return limbs as unknown as M31Secret\n}\n\n/**\n * Convert a hex hash output to an M31 digest (4 elements).\n *\n * Splits 32 bytes into 4 × 8-byte LE chunks, reduces each mod M31_P.\n */\nfunction bytesToM31Digest(hashHex: `0x${string}`): M31Digest {\n const bytes = hexToUint8Array(hashHex)\n const digest: bigint[] = []\n\n for (let i = 0; i < DIGEST_SIZE; i++) {\n const offset = i * 8\n // Read 8 bytes as little-endian uint64\n let val = 0n\n for (let j = 0; j < 8; j++) {\n val |= BigInt(bytes[offset + j]!) << BigInt(j * 8)\n }\n digest.push(val % M31_P)\n }\n\n return digest as unknown as M31Digest\n}\n\n/**\n * Convert hex string to Uint8Array\n */\nfunction hexToUint8Array(hex: `0x${string}`): Uint8Array {\n const str = hex.slice(2)\n const bytes = new Uint8Array(str.length / 2)\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(str.slice(i * 2, i * 2 + 2), 16)\n }\n return bytes\n}\n"]}
1
+ {"version":3,"sources":["../src/utils/keccak-m31.ts"],"names":["init_crypto","keccak256","bytesToHex"],"mappings":"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","file":"chunk-U3YFYMWF.cjs","sourcesContent":["/**\n * Keccak-256 hashing over M31 field elements.\n *\n * This module implements the same hashing algorithm as the Rust Stwo prover\n * (stwo-prover/src/hash.rs), producing identical outputs for identical inputs.\n *\n * Algorithm:\n * 1. Each M31 element is encoded as 4 little-endian bytes\n * 2. All encoded bytes are concatenated and fed to Keccak-256\n * 3. The 32-byte output is split into 4 chunks of 8 bytes\n * 4. Each chunk is read as a little-endian uint64 and reduced mod M31_P\n *\n * M31 field: p = 2^31 - 1 = 2,147,483,647\n */\n\nimport { keccak256 } from 'viem'\nimport { bytesToHex } from './crypto.js'\n\n/** The M31 prime: 2^31 - 1 */\nexport const M31_P = 2147483647n\n\n/** Number of M31 elements in a digest */\nexport const DIGEST_SIZE = 4\n\n/** Number of M31 limbs for owner secrets (248 bits of entropy) */\nexport const SECRET_LIMBS = 8\n\n/** M31 digest type: tuple of 4 M31 values */\nexport type M31Digest = readonly [bigint, bigint, bigint, bigint]\n\n/** M31 secret type: tuple of 8 M31 values */\nexport type M31Secret = readonly [bigint, bigint, bigint, bigint, bigint, bigint, bigint, bigint]\n\n/**\n * Hash arbitrary M31 elements using Keccak-256.\n *\n * Matches Rust: `hash_m31(inputs: &[M31]) -> [M31; 4]`\n *\n * Each M31 is encoded as 4 little-endian bytes. The keccak output\n * is split into 4 × 8-byte LE chunks, each reduced mod M31_P.\n */\nexport function keccakM31(inputs: readonly bigint[]): M31Digest {\n // Encode each M31 as 4 little-endian bytes\n const bytes = new Uint8Array(inputs.length * 4)\n for (let i = 0; i < inputs.length; i++) {\n const val = Number(inputs[i]! & 0xFFFFFFFFn)\n const offset = i * 4\n bytes[offset] = val & 0xFF\n bytes[offset + 1] = (val >> 8) & 0xFF\n bytes[offset + 2] = (val >> 16) & 0xFF\n bytes[offset + 3] = (val >> 24) & 0xFF\n }\n\n // Keccak-256\n const hashHex = keccak256(bytesToHex(bytes))\n\n // Parse 32-byte output into 4 × uint64 LE, reduce mod M31_P\n return bytesToM31Digest(hashHex)\n}\n\n/**\n * Hash two M31 elements (Merkle tree node hash).\n *\n * Matches Rust: `hash_two(left: M31, right: M31) -> [M31; 4]`\n */\nexport function keccakHashTwo(left: bigint, right: bigint): M31Digest {\n return keccakM31([left, right])\n}\n\n/**\n * Compute owner hash from an 8-limb secret.\n *\n * Matches Rust: `compute_owner_hash(owner_secret: &[M31; 8]) -> [M31; 4]`\n */\nexport function computeStarkOwnerHash(ownerSecret: M31Secret): M31Digest {\n return keccakM31(ownerSecret)\n}\n\n/**\n * Compute a STARK note commitment.\n *\n * Matches Rust: `compute_commitment(amount, owner_hash, blinding, origin, token)`\n *\n * Input order: [amount, ownerHash[0], ownerHash[1], ownerHash[2], ownerHash[3], blinding, origin, token]\n */\nexport function computeStarkCommitment(\n amount: bigint,\n ownerHash: M31Digest,\n blinding: bigint,\n origin: bigint,\n token: bigint,\n): M31Digest {\n return keccakM31([\n amount,\n ownerHash[0],\n ownerHash[1],\n ownerHash[2],\n ownerHash[3],\n blinding,\n origin,\n token,\n ])\n}\n\n/**\n * Compute a STARK nullifier.\n *\n * Matches Rust: `compute_nullifier(owner_secret, leaf_index, commitment)`\n *\n * Input order: [ownerSecret[0..8], leafIndex, commitment[0..4]]\n */\nexport function computeStarkNullifier(\n ownerSecret: M31Secret,\n leafIndex: bigint,\n commitment: M31Digest,\n): M31Digest {\n return keccakM31([\n ...ownerSecret,\n leafIndex,\n ...commitment,\n ])\n}\n\n/**\n * Split a 32-byte keccak hash into 8 M31 limbs.\n *\n * Used for deriving STARK spending/viewing secrets from a seed.\n * Each limb is 4 bytes of the hash, read as LE uint32, reduced mod M31_P.\n */\nexport function splitToM31Limbs(hashHex: `0x${string}`): M31Secret {\n const bytes = hexToUint8Array(hashHex)\n const limbs: bigint[] = []\n for (let i = 0; i < SECRET_LIMBS; i++) {\n const offset = i * 4\n const val = (bytes[offset]!)\n | ((bytes[offset + 1]!) << 8)\n | ((bytes[offset + 2]!) << 16)\n | ((bytes[offset + 3]!) << 24)\n limbs.push(BigInt(val >>> 0) % M31_P)\n }\n return limbs as unknown as M31Secret\n}\n\n/**\n * Convert a hex hash output to an M31 digest (4 elements).\n *\n * Splits 32 bytes into 4 × 8-byte LE chunks, reduces each mod M31_P.\n */\nfunction bytesToM31Digest(hashHex: `0x${string}`): M31Digest {\n const bytes = hexToUint8Array(hashHex)\n const digest: bigint[] = []\n\n for (let i = 0; i < DIGEST_SIZE; i++) {\n const offset = i * 8\n // Read 8 bytes as little-endian uint64\n let val = 0n\n for (let j = 0; j < 8; j++) {\n val |= BigInt(bytes[offset + j]!) << BigInt(j * 8)\n }\n digest.push(val % M31_P)\n }\n\n return digest as unknown as M31Digest\n}\n\n/**\n * Convert hex string to Uint8Array\n */\nfunction hexToUint8Array(hex: `0x${string}`): Uint8Array {\n const str = hex.slice(2)\n const bytes = new Uint8Array(str.length / 2)\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(str.slice(i * 2, i * 2 + 2), 16)\n }\n return bytes\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkJWNXBALH_cjs = require('./chunk-JWNXBALH.cjs');
3
+ var chunkHEHXSV47_cjs = require('./chunk-HEHXSV47.cjs');
4
4
  var chunkG7VZBCD6_cjs = require('./chunk-G7VZBCD6.cjs');
5
5
 
6
6
  // src/utils/crypto.ts
@@ -15,7 +15,7 @@ function randomFieldElement() {
15
15
  for (let i = 0; i < bytes.length; i++) {
16
16
  value = (value << 8n) + BigInt(bytes[i]);
17
17
  }
18
- return value % chunkJWNXBALH_cjs.FIELD_PRIME;
18
+ return value % chunkHEHXSV47_cjs.FIELD_PRIME;
19
19
  }
20
20
  function bytesToHex(bytes) {
21
21
  return `0x${Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("")}`;
@@ -46,7 +46,7 @@ function bytesToBigint(bytes) {
46
46
  }
47
47
  var init_crypto = chunkG7VZBCD6_cjs.__esm({
48
48
  "src/utils/crypto.ts"() {
49
- chunkJWNXBALH_cjs.init_poseidon();
49
+ chunkHEHXSV47_cjs.init_poseidon();
50
50
  }
51
51
  });
52
52
 
@@ -57,5 +57,5 @@ exports.hexToBytes = hexToBytes;
57
57
  exports.init_crypto = init_crypto;
58
58
  exports.randomBytes = randomBytes;
59
59
  exports.randomFieldElement = randomFieldElement;
60
- //# sourceMappingURL=chunk-3HQ7A6ZM.cjs.map
61
- //# sourceMappingURL=chunk-3HQ7A6ZM.cjs.map
60
+ //# sourceMappingURL=chunk-UFEDJJSH.cjs.map
61
+ //# sourceMappingURL=chunk-UFEDJJSH.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/crypto.ts"],"names":["FIELD_PRIME","__esm","init_poseidon"],"mappings":";;;;;;AAWO,SAAS,YAAY,MAAA,EAA4B;AACtD,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,MAAM,CAAA;AACnC,EAAA,MAAA,CAAO,gBAAgB,KAAK,CAAA;AAC5B,EAAA,OAAO,KAAA;AACT;AAOO,SAAS,kBAAA,GAA6B;AAE3C,EAAA,MAAM,KAAA,GAAQ,YAAY,EAAE,CAAA;AAG5B,EAAA,IAAI,KAAA,GAAQ,EAAA;AACZ,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,KAAA,GAAA,CAAS,KAAA,IAAS,EAAA,IAAM,MAAA,CAAO,KAAA,CAAM,CAAC,CAAE,CAAA;AAAA,EAC1C;AAGA,EAAA,OAAO,KAAA,GAAQA,6BAAA;AACjB;AAKO,SAAS,WAAW,KAAA,EAAkC;AAC3D,EAAA,OAAO,KAAK,KAAA,CAAM,IAAA,CAAK,KAAK,CAAA,CACzB,GAAA,CAAI,OAAK,CAAA,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,SAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CACxC,IAAA,CAAK,EAAE,CAAC,CAAA,CAAA;AACb;AAKO,SAAS,WAAW,GAAA,EAAgC;AACzD,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,KAAA,CAAM,CAAC,CAAA;AACvB,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,GAAA,CAAI,SAAS,CAAC,CAAA;AAC3C,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,KAAA,CAAM,CAAC,CAAA,GAAI,QAAA,CAAS,GAAA,CAAI,KAAA,CAAM,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,GAAI,CAAC,CAAA,EAAG,EAAE,CAAA;AAAA,EACrD;AACA,EAAA,OAAO,KAAA;AACT;AAKO,SAAS,aAAA,CAAc,OAAe,MAAA,EAA4B;AACvE,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,MAAM,CAAA;AACnC,EAAA,IAAI,IAAA,GAAO,KAAA;AACX,EAAA,KAAA,IAAS,CAAA,GAAI,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AACpC,IAAA,KAAA,CAAM,CAAC,CAAA,GAAI,MAAA,CAAO,IAAA,GAAO,KAAK,CAAA;AAC9B,IAAA,IAAA,KAAS,EAAA;AAAA,EACX;AACA,EAAA,OAAO,KAAA;AACT;AAKO,SAAS,cAAc,KAAA,EAA2B;AACvD,EAAA,IAAI,KAAA,GAAQ,EAAA;AACZ,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,KAAA,GAAA,CAAS,KAAA,IAAS,EAAA,IAAM,MAAA,CAAO,KAAA,CAAM,CAAC,CAAE,CAAA;AAAA,EAC1C;AACA,EAAA,OAAO,KAAA;AACT;AA/EA,IAAA,WAAA,GAAAC,uBAAA,CAAA;AAAA,EAAA,qBAAA,GAAA;AAMA,IAAAC,+BAAA,EAAA;AAAA,EAAA;AAAA,CAAA","file":"chunk-3HQ7A6ZM.cjs","sourcesContent":["/**\n * Cryptographic Utilities\n *\n * Secure random number generation and field arithmetic.\n */\n\nimport { FIELD_PRIME } from './poseidon.js'\n\n/**\n * Generate cryptographically secure random bytes\n */\nexport function randomBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length)\n crypto.getRandomValues(bytes)\n return bytes\n}\n\n/**\n * Generate a random field element (for blinding factors, etc.)\n *\n * Returns a value in range [0, FIELD_PRIME)\n */\nexport function randomFieldElement(): bigint {\n // Generate 32 bytes of randomness\n const bytes = randomBytes(32)\n\n // Convert to bigint\n let value = 0n\n for (let i = 0; i < bytes.length; i++) {\n value = (value << 8n) + BigInt(bytes[i]!)\n }\n\n // Reduce modulo field prime\n return value % FIELD_PRIME\n}\n\n/**\n * Convert bytes to hex string\n */\nexport function bytesToHex(bytes: Uint8Array): `0x${string}` {\n return `0x${Array.from(bytes)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('')}`\n}\n\n/**\n * Convert hex string to bytes\n */\nexport function hexToBytes(hex: `0x${string}`): Uint8Array {\n const str = hex.slice(2)\n const bytes = new Uint8Array(str.length / 2)\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(str.slice(i * 2, i * 2 + 2), 16)\n }\n return bytes\n}\n\n/**\n * Convert bigint to bytes (big-endian)\n */\nexport function bigintToBytes(value: bigint, length: number): Uint8Array {\n const bytes = new Uint8Array(length)\n let temp = value\n for (let i = length - 1; i >= 0; i--) {\n bytes[i] = Number(temp & 0xffn)\n temp >>= 8n\n }\n return bytes\n}\n\n/**\n * Convert bytes to bigint (big-endian)\n */\nexport function bytesToBigint(bytes: Uint8Array): bigint {\n let value = 0n\n for (let i = 0; i < bytes.length; i++) {\n value = (value << 8n) + BigInt(bytes[i]!)\n }\n return value\n}\n\n/**\n * Modular exponentiation: base^exp mod modulus\n */\nexport function modPow(base: bigint, exp: bigint, modulus: bigint): bigint {\n let result = 1n\n base = base % modulus\n\n while (exp > 0n) {\n if (exp % 2n === 1n) {\n result = (result * base) % modulus\n }\n exp = exp >> 1n\n base = (base * base) % modulus\n }\n\n return result\n}\n\n/**\n * Modular inverse using extended Euclidean algorithm\n */\nexport function modInverse(a: bigint, modulus: bigint): bigint {\n let [oldR, r] = [a, modulus]\n let [oldS, s] = [1n, 0n]\n\n while (r !== 0n) {\n const quotient = oldR / r\n ;[oldR, r] = [r, oldR - quotient * r]\n ;[oldS, s] = [s, oldS - quotient * s]\n }\n\n if (oldR !== 1n) {\n throw new Error('Modular inverse does not exist')\n }\n\n return ((oldS % modulus) + modulus) % modulus\n}\n"]}
1
+ {"version":3,"sources":["../src/utils/crypto.ts"],"names":["FIELD_PRIME","__esm","init_poseidon"],"mappings":";;;;;;AAWO,SAAS,YAAY,MAAA,EAA4B;AACtD,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,MAAM,CAAA;AACnC,EAAA,MAAA,CAAO,gBAAgB,KAAK,CAAA;AAC5B,EAAA,OAAO,KAAA;AACT;AAOO,SAAS,kBAAA,GAA6B;AAE3C,EAAA,MAAM,KAAA,GAAQ,YAAY,EAAE,CAAA;AAG5B,EAAA,IAAI,KAAA,GAAQ,EAAA;AACZ,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,KAAA,GAAA,CAAS,KAAA,IAAS,EAAA,IAAM,MAAA,CAAO,KAAA,CAAM,CAAC,CAAE,CAAA;AAAA,EAC1C;AAGA,EAAA,OAAO,KAAA,GAAQA,6BAAA;AACjB;AAKO,SAAS,WAAW,KAAA,EAAkC;AAC3D,EAAA,OAAO,KAAK,KAAA,CAAM,IAAA,CAAK,KAAK,CAAA,CACzB,GAAA,CAAI,OAAK,CAAA,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,SAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CACxC,IAAA,CAAK,EAAE,CAAC,CAAA,CAAA;AACb;AAKO,SAAS,WAAW,GAAA,EAAgC;AACzD,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,KAAA,CAAM,CAAC,CAAA;AACvB,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,GAAA,CAAI,SAAS,CAAC,CAAA;AAC3C,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,KAAA,CAAM,CAAC,CAAA,GAAI,QAAA,CAAS,GAAA,CAAI,KAAA,CAAM,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,GAAI,CAAC,CAAA,EAAG,EAAE,CAAA;AAAA,EACrD;AACA,EAAA,OAAO,KAAA;AACT;AAKO,SAAS,aAAA,CAAc,OAAe,MAAA,EAA4B;AACvE,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,MAAM,CAAA;AACnC,EAAA,IAAI,IAAA,GAAO,KAAA;AACX,EAAA,KAAA,IAAS,CAAA,GAAI,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AACpC,IAAA,KAAA,CAAM,CAAC,CAAA,GAAI,MAAA,CAAO,IAAA,GAAO,KAAK,CAAA;AAC9B,IAAA,IAAA,KAAS,EAAA;AAAA,EACX;AACA,EAAA,OAAO,KAAA;AACT;AAKO,SAAS,cAAc,KAAA,EAA2B;AACvD,EAAA,IAAI,KAAA,GAAQ,EAAA;AACZ,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,KAAA,GAAA,CAAS,KAAA,IAAS,EAAA,IAAM,MAAA,CAAO,KAAA,CAAM,CAAC,CAAE,CAAA;AAAA,EAC1C;AACA,EAAA,OAAO,KAAA;AACT;AA/EA,IAAA,WAAA,GAAAC,uBAAA,CAAA;AAAA,EAAA,qBAAA,GAAA;AAMA,IAAAC,+BAAA,EAAA;AAAA,EAAA;AAAA,CAAA","file":"chunk-UFEDJJSH.cjs","sourcesContent":["/**\n * Cryptographic Utilities\n *\n * Secure random number generation and field arithmetic.\n */\n\nimport { FIELD_PRIME } from './poseidon.js'\n\n/**\n * Generate cryptographically secure random bytes\n */\nexport function randomBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length)\n crypto.getRandomValues(bytes)\n return bytes\n}\n\n/**\n * Generate a random field element (for blinding factors, etc.)\n *\n * Returns a value in range [0, FIELD_PRIME)\n */\nexport function randomFieldElement(): bigint {\n // Generate 32 bytes of randomness\n const bytes = randomBytes(32)\n\n // Convert to bigint\n let value = 0n\n for (let i = 0; i < bytes.length; i++) {\n value = (value << 8n) + BigInt(bytes[i]!)\n }\n\n // Reduce modulo field prime\n return value % FIELD_PRIME\n}\n\n/**\n * Convert bytes to hex string\n */\nexport function bytesToHex(bytes: Uint8Array): `0x${string}` {\n return `0x${Array.from(bytes)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('')}`\n}\n\n/**\n * Convert hex string to bytes\n */\nexport function hexToBytes(hex: `0x${string}`): Uint8Array {\n const str = hex.slice(2)\n const bytes = new Uint8Array(str.length / 2)\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(str.slice(i * 2, i * 2 + 2), 16)\n }\n return bytes\n}\n\n/**\n * Convert bigint to bytes (big-endian)\n */\nexport function bigintToBytes(value: bigint, length: number): Uint8Array {\n const bytes = new Uint8Array(length)\n let temp = value\n for (let i = length - 1; i >= 0; i--) {\n bytes[i] = Number(temp & 0xffn)\n temp >>= 8n\n }\n return bytes\n}\n\n/**\n * Convert bytes to bigint (big-endian)\n */\nexport function bytesToBigint(bytes: Uint8Array): bigint {\n let value = 0n\n for (let i = 0; i < bytes.length; i++) {\n value = (value << 8n) + BigInt(bytes[i]!)\n }\n return value\n}\n\n/**\n * Modular exponentiation: base^exp mod modulus\n */\nexport function modPow(base: bigint, exp: bigint, modulus: bigint): bigint {\n let result = 1n\n base = base % modulus\n\n while (exp > 0n) {\n if (exp % 2n === 1n) {\n result = (result * base) % modulus\n }\n exp = exp >> 1n\n base = (base * base) % modulus\n }\n\n return result\n}\n\n/**\n * Modular inverse using extended Euclidean algorithm\n */\nexport function modInverse(a: bigint, modulus: bigint): bigint {\n let [oldR, r] = [a, modulus]\n let [oldS, s] = [1n, 0n]\n\n while (r !== 0n) {\n const quotient = oldR / r\n ;[oldR, r] = [r, oldR - quotient * r]\n ;[oldS, s] = [s, oldS - quotient * s]\n }\n\n if (oldR !== 1n) {\n throw new Error('Modular inverse does not exist')\n }\n\n return ((oldS % modulus) + modulus) % modulus\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { init_poseidon, FIELD_PRIME } from './chunk-V23OSL25.js';
1
+ import { init_poseidon, FIELD_PRIME } from './chunk-5QSSX3KR.js';
2
2
  import { __esm } from './chunk-Z6ZWNWWR.js';
3
3
 
4
4
  // src/utils/crypto.ts
@@ -49,5 +49,5 @@ var init_crypto = __esm({
49
49
  });
50
50
 
51
51
  export { bigintToBytes, bytesToBigint, bytesToHex, hexToBytes, init_crypto, randomBytes, randomFieldElement };
52
- //# sourceMappingURL=chunk-W77GRBO4.js.map
53
- //# sourceMappingURL=chunk-W77GRBO4.js.map
52
+ //# sourceMappingURL=chunk-UQIM2KT3.js.map
53
+ //# sourceMappingURL=chunk-UQIM2KT3.js.map