@whetstone-research/doppler-sdk 0.0.1-alpha.9 → 0.0.1

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 (368) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +726 -25
  3. package/dist/DopplerSDK.d.mts +45 -7
  4. package/dist/DopplerSDK.d.ts +45 -7
  5. package/dist/DopplerSDK.js +35 -12
  6. package/dist/DopplerSDK.mjs +34 -11
  7. package/dist/abis/bytecodes.d.mts +3 -2
  8. package/dist/abis/bytecodes.d.ts +3 -2
  9. package/dist/abis/bytecodes.js +9 -6
  10. package/dist/abis/bytecodes.mjs +1 -2
  11. package/dist/abis/index.d.mts +1507 -129
  12. package/dist/abis/index.d.ts +1507 -129
  13. package/dist/abis/index.js +43 -20
  14. package/dist/abis/index.mjs +2 -3
  15. package/dist/addresses.d.mts +16 -3
  16. package/dist/addresses.d.ts +16 -3
  17. package/dist/addresses.js +13 -5
  18. package/dist/addresses.mjs +2 -2
  19. package/dist/builders/DynamicAuctionBuilder.d.mts +119 -0
  20. package/dist/builders/DynamicAuctionBuilder.d.ts +119 -0
  21. package/dist/builders/DynamicAuctionBuilder.js +29 -0
  22. package/dist/builders/DynamicAuctionBuilder.js.map +1 -0
  23. package/dist/builders/DynamicAuctionBuilder.mjs +20 -0
  24. package/dist/builders/DynamicAuctionBuilder.mjs.map +1 -0
  25. package/dist/builders/MulticurveBuilder.d.mts +132 -0
  26. package/dist/builders/MulticurveBuilder.d.ts +132 -0
  27. package/dist/builders/MulticurveBuilder.js +29 -0
  28. package/dist/builders/MulticurveBuilder.js.map +1 -0
  29. package/dist/builders/MulticurveBuilder.mjs +20 -0
  30. package/dist/builders/MulticurveBuilder.mjs.map +1 -0
  31. package/dist/builders/StaticAuctionBuilder.d.mts +124 -0
  32. package/dist/builders/StaticAuctionBuilder.d.ts +124 -0
  33. package/dist/builders/StaticAuctionBuilder.js +29 -0
  34. package/dist/builders/StaticAuctionBuilder.js.map +1 -0
  35. package/dist/builders/StaticAuctionBuilder.mjs +20 -0
  36. package/dist/builders/StaticAuctionBuilder.mjs.map +1 -0
  37. package/dist/builders/index.d.mts +8 -0
  38. package/dist/builders/index.d.ts +8 -0
  39. package/dist/builders/index.js +56 -0
  40. package/dist/builders/index.js.map +1 -0
  41. package/dist/builders/index.mjs +23 -0
  42. package/dist/builders/index.mjs.map +1 -0
  43. package/dist/builders/shared.d.mts +116 -0
  44. package/dist/builders/shared.d.ts +116 -0
  45. package/dist/builders/shared.js +39 -0
  46. package/dist/builders/shared.js.map +1 -0
  47. package/dist/builders/shared.mjs +18 -0
  48. package/dist/builders/shared.mjs.map +1 -0
  49. package/dist/builders.d.mts +8 -131
  50. package/dist/builders.d.ts +8 -131
  51. package/dist/builders.js +44 -5
  52. package/dist/builders.mjs +22 -3
  53. package/dist/chunk-3PNCB4W5.js +4 -0
  54. package/dist/{chunk-KRN3ROUE.js.map → chunk-3PNCB4W5.js.map} +1 -1
  55. package/dist/chunk-3RK7LRAA.js +282 -0
  56. package/dist/chunk-3RK7LRAA.js.map +1 -0
  57. package/dist/chunk-4HM3ERBU.js +13 -0
  58. package/dist/chunk-4HM3ERBU.js.map +1 -0
  59. package/dist/{chunk-7W72MFJO.mjs → chunk-4TROGENW.mjs} +5 -4
  60. package/dist/chunk-4TROGENW.mjs.map +1 -0
  61. package/dist/chunk-5TL5V6UX.mjs +3 -0
  62. package/dist/{chunk-AZLFJNTG.mjs.map → chunk-5TL5V6UX.mjs.map} +1 -1
  63. package/dist/chunk-64AWG57M.mjs +192 -0
  64. package/dist/chunk-64AWG57M.mjs.map +1 -0
  65. package/dist/chunk-6KWCHTK3.js +166 -0
  66. package/dist/chunk-6KWCHTK3.js.map +1 -0
  67. package/dist/chunk-6OOWOPCX.js +1708 -0
  68. package/dist/chunk-6OOWOPCX.js.map +1 -0
  69. package/dist/chunk-7BBRPWQJ.js +257 -0
  70. package/dist/chunk-7BBRPWQJ.js.map +1 -0
  71. package/dist/{chunk-AQPINKEW.mjs → chunk-AKSEBAR7.mjs} +29 -19
  72. package/dist/chunk-AKSEBAR7.mjs.map +1 -0
  73. package/dist/chunk-AS64GWBX.js +204 -0
  74. package/dist/chunk-AS64GWBX.js.map +1 -0
  75. package/dist/chunk-AULFBXM5.mjs +331 -0
  76. package/dist/chunk-AULFBXM5.mjs.map +1 -0
  77. package/dist/chunk-AW3WR2D3.mjs +238 -0
  78. package/dist/chunk-AW3WR2D3.mjs.map +1 -0
  79. package/dist/chunk-BIQQ53O2.js +45 -0
  80. package/dist/chunk-BIQQ53O2.js.map +1 -0
  81. package/dist/chunk-C6MPV3CY.js +260 -0
  82. package/dist/chunk-C6MPV3CY.js.map +1 -0
  83. package/dist/{chunk-AYPP5JEQ.mjs → chunk-CLEQO6GU.mjs} +5 -5
  84. package/dist/chunk-CLEQO6GU.mjs.map +1 -0
  85. package/dist/chunk-CVHPLURA.js +147 -0
  86. package/dist/chunk-CVHPLURA.js.map +1 -0
  87. package/dist/chunk-D2RBCFNW.mjs +130 -0
  88. package/dist/chunk-D2RBCFNW.mjs.map +1 -0
  89. package/dist/chunk-ECD4FV3A.mjs +11 -0
  90. package/dist/chunk-ECD4FV3A.mjs.map +1 -0
  91. package/dist/chunk-EDJBZPMW.mjs +255 -0
  92. package/dist/chunk-EDJBZPMW.mjs.map +1 -0
  93. package/dist/chunk-FPAI4QYW.mjs +145 -0
  94. package/dist/chunk-FPAI4QYW.mjs.map +1 -0
  95. package/dist/chunk-HM25ZMO3.js +18 -0
  96. package/dist/chunk-HM25ZMO3.js.map +1 -0
  97. package/dist/chunk-IHC6UYKK.js +4 -0
  98. package/dist/{chunk-DRBRT57F.js.map → chunk-IHC6UYKK.js.map} +1 -1
  99. package/dist/{chunk-AXA7YT2G.mjs → chunk-J5BFFL3X.mjs} +87 -47
  100. package/dist/chunk-J5BFFL3X.mjs.map +1 -0
  101. package/dist/chunk-JIKAD4YL.js +4 -0
  102. package/dist/{chunk-KEXKKQVW.js.map → chunk-JIKAD4YL.js.map} +1 -1
  103. package/dist/{chunk-EFAPDN4J.js → chunk-JWEXGALU.js} +730 -33
  104. package/dist/chunk-JWEXGALU.js.map +1 -0
  105. package/dist/{chunk-4K5GBNQV.mjs → chunk-KDT76YQE.mjs} +52 -13
  106. package/dist/chunk-KDT76YQE.mjs.map +1 -0
  107. package/dist/chunk-LMQLMMEX.js +317 -0
  108. package/dist/chunk-LMQLMMEX.js.map +1 -0
  109. package/dist/{chunk-TOMVBPNZ.js → chunk-LS4TK6SX.js} +9 -4
  110. package/dist/chunk-LS4TK6SX.js.map +1 -0
  111. package/dist/chunk-M4WMHD3X.mjs +40 -0
  112. package/dist/chunk-M4WMHD3X.mjs.map +1 -0
  113. package/dist/chunk-MCOK3UFR.mjs +280 -0
  114. package/dist/chunk-MCOK3UFR.mjs.map +1 -0
  115. package/dist/chunk-MGQSQCFG.js +176 -0
  116. package/dist/chunk-MGQSQCFG.js.map +1 -0
  117. package/dist/chunk-MKE3BUL3.mjs +3 -0
  118. package/dist/{chunk-CYDWEPFL.mjs.map → chunk-MKE3BUL3.mjs.map} +1 -1
  119. package/dist/chunk-MNJ5OYPE.mjs +17 -0
  120. package/dist/chunk-MNJ5OYPE.mjs.map +1 -0
  121. package/dist/chunk-MNXD45J7.mjs +164 -0
  122. package/dist/chunk-MNXD45J7.mjs.map +1 -0
  123. package/dist/chunk-NGDPQC5E.js +333 -0
  124. package/dist/chunk-NGDPQC5E.js.map +1 -0
  125. package/dist/chunk-NNNCVFOH.mjs +16 -0
  126. package/dist/chunk-NNNCVFOH.mjs.map +1 -0
  127. package/dist/chunk-NZ4BJ2IC.mjs +315 -0
  128. package/dist/chunk-NZ4BJ2IC.mjs.map +1 -0
  129. package/dist/chunk-OKNM7ODQ.js +29 -0
  130. package/dist/chunk-OKNM7ODQ.js.map +1 -0
  131. package/dist/{chunk-DCFHANLR.mjs → chunk-OTG75GVH.mjs} +725 -34
  132. package/dist/chunk-OTG75GVH.mjs.map +1 -0
  133. package/dist/chunk-OZ6DGBRL.mjs +25 -0
  134. package/dist/chunk-OZ6DGBRL.mjs.map +1 -0
  135. package/dist/chunk-P25HBGP5.mjs +3 -0
  136. package/dist/chunk-P25HBGP5.mjs.map +1 -0
  137. package/dist/{chunk-XG7K4R56.js → chunk-P7KLEPVI.js} +52 -12
  138. package/dist/chunk-P7KLEPVI.js.map +1 -0
  139. package/dist/{chunk-OPKQMN46.mjs → chunk-PAPXGPJB.mjs} +9 -4
  140. package/dist/chunk-PAPXGPJB.mjs.map +1 -0
  141. package/dist/chunk-PCNXJAU5.js +19 -0
  142. package/dist/chunk-PCNXJAU5.js.map +1 -0
  143. package/dist/{chunk-PMIJTXU6.js → chunk-PD6HWEMG.js} +40 -30
  144. package/dist/chunk-PD6HWEMG.js.map +1 -0
  145. package/dist/{chunk-ER42VG7H.js → chunk-PH2KXREH.js} +20 -3
  146. package/dist/chunk-PH2KXREH.js.map +1 -0
  147. package/dist/chunk-Q5ERW5ZW.mjs +107 -0
  148. package/dist/chunk-Q5ERW5ZW.mjs.map +1 -0
  149. package/dist/chunk-Q7YNBSVH.js +28 -0
  150. package/dist/chunk-Q7YNBSVH.js.map +1 -0
  151. package/dist/{chunk-T644D54P.mjs → chunk-QKO2FZGN.mjs} +16 -4
  152. package/dist/chunk-QKO2FZGN.mjs.map +1 -0
  153. package/dist/{chunk-CIRZKWLL.js → chunk-RVFSRYI5.js} +5 -3
  154. package/dist/chunk-RVFSRYI5.js.map +1 -0
  155. package/dist/{chunk-KPBCG4X2.js → chunk-RW37KJ77.js} +11 -11
  156. package/dist/chunk-RW37KJ77.js.map +1 -0
  157. package/dist/chunk-SD7BHT2F.mjs +3 -0
  158. package/dist/chunk-SD7BHT2F.mjs.map +1 -0
  159. package/dist/chunk-SP5M57BG.mjs +258 -0
  160. package/dist/chunk-SP5M57BG.mjs.map +1 -0
  161. package/dist/chunk-TKSHYEYA.mjs +1706 -0
  162. package/dist/chunk-TKSHYEYA.mjs.map +1 -0
  163. package/dist/chunk-WTS75RUC.js +4 -0
  164. package/dist/chunk-WTS75RUC.js.map +1 -0
  165. package/dist/{chunk-EIRVZJTT.js → chunk-XRPIGMA2.js} +108 -68
  166. package/dist/chunk-XRPIGMA2.js.map +1 -0
  167. package/dist/chunk-XTKSM4QE.js +132 -0
  168. package/dist/chunk-XTKSM4QE.js.map +1 -0
  169. package/dist/chunk-XUE3CIJ5.mjs +174 -0
  170. package/dist/chunk-XUE3CIJ5.mjs.map +1 -0
  171. package/dist/chunk-YYUOLM6U.js +244 -0
  172. package/dist/chunk-YYUOLM6U.js.map +1 -0
  173. package/dist/chunk-ZH44DHVR.mjs +26 -0
  174. package/dist/chunk-ZH44DHVR.mjs.map +1 -0
  175. package/dist/chunk-ZPHOOG72.js +112 -0
  176. package/dist/chunk-ZPHOOG72.js.map +1 -0
  177. package/dist/constants.d.mts +7 -2
  178. package/dist/constants.d.ts +7 -2
  179. package/dist/constants.js +57 -38
  180. package/dist/constants.mjs +1 -2
  181. package/dist/deployments.generated.d.mts +2 -0
  182. package/dist/deployments.generated.d.ts +2 -0
  183. package/dist/deployments.generated.js +12 -0
  184. package/dist/deployments.generated.js.map +1 -0
  185. package/dist/deployments.generated.mjs +3 -0
  186. package/dist/deployments.generated.mjs.map +1 -0
  187. package/dist/entities/DopplerFactory.d.mts +139 -11
  188. package/dist/entities/DopplerFactory.d.ts +139 -11
  189. package/dist/entities/DopplerFactory.js +17 -7
  190. package/dist/entities/DopplerFactory.mjs +16 -6
  191. package/dist/entities/auction/DynamicAuction.d.mts +19 -4
  192. package/dist/entities/auction/DynamicAuction.d.ts +19 -4
  193. package/dist/entities/auction/DynamicAuction.js +6 -6
  194. package/dist/entities/auction/DynamicAuction.mjs +5 -5
  195. package/dist/entities/auction/MulticurvePool.d.mts +55 -0
  196. package/dist/entities/auction/MulticurvePool.d.ts +55 -0
  197. package/dist/entities/auction/MulticurvePool.js +18 -0
  198. package/dist/entities/auction/MulticurvePool.js.map +1 -0
  199. package/dist/entities/auction/MulticurvePool.mjs +9 -0
  200. package/dist/entities/auction/MulticurvePool.mjs.map +1 -0
  201. package/dist/entities/auction/StaticAuction.d.mts +6 -3
  202. package/dist/entities/auction/StaticAuction.d.ts +6 -3
  203. package/dist/entities/auction/StaticAuction.js +6 -6
  204. package/dist/entities/auction/StaticAuction.mjs +5 -5
  205. package/dist/entities/auction/index.d.mts +3 -0
  206. package/dist/entities/auction/index.d.ts +3 -0
  207. package/dist/entities/auction/index.js +16 -9
  208. package/dist/entities/auction/index.mjs +10 -7
  209. package/dist/entities/quoter/Quoter.d.mts +44 -2
  210. package/dist/entities/quoter/Quoter.d.ts +44 -2
  211. package/dist/entities/quoter/Quoter.js +6 -6
  212. package/dist/entities/quoter/Quoter.mjs +5 -5
  213. package/dist/entities/quoter/index.d.mts +3 -0
  214. package/dist/entities/quoter/index.d.ts +3 -0
  215. package/dist/entities/quoter/index.js +6 -6
  216. package/dist/entities/quoter/index.mjs +5 -5
  217. package/dist/entities/token/derc20/Derc20.d.mts +33 -7
  218. package/dist/entities/token/derc20/Derc20.d.ts +33 -7
  219. package/dist/entities/token/derc20/Derc20.js +4 -5
  220. package/dist/entities/token/derc20/Derc20.mjs +3 -4
  221. package/dist/entities/token/derc20/index.d.mts +3 -0
  222. package/dist/entities/token/derc20/index.d.ts +3 -0
  223. package/dist/entities/token/derc20/index.js +4 -5
  224. package/dist/entities/token/derc20/index.mjs +3 -4
  225. package/dist/entities/token/eth/Eth.d.mts +7 -3
  226. package/dist/entities/token/eth/Eth.d.ts +7 -3
  227. package/dist/entities/token/eth/Eth.js +2 -3
  228. package/dist/entities/token/eth/Eth.mjs +1 -2
  229. package/dist/entities/token/eth/index.d.mts +3 -0
  230. package/dist/entities/token/eth/index.d.ts +3 -0
  231. package/dist/entities/token/eth/index.js +2 -3
  232. package/dist/entities/token/eth/index.mjs +1 -2
  233. package/dist/entities/token/index.d.mts +3 -0
  234. package/dist/entities/token/index.d.ts +3 -0
  235. package/dist/entities/token/index.js +6 -7
  236. package/dist/entities/token/index.mjs +4 -5
  237. package/dist/index.d.mts +18 -6
  238. package/dist/index.d.ts +18 -6
  239. package/dist/index.js +305 -140
  240. package/dist/index.js.map +1 -1
  241. package/dist/index.mjs +32 -19
  242. package/dist/index.mjs.map +1 -1
  243. package/dist/types.d.mts +260 -22
  244. package/dist/types.d.ts +260 -22
  245. package/dist/types.js +12 -3
  246. package/dist/types.mjs +3 -2
  247. package/dist/utils/airlock.d.mts +11 -0
  248. package/dist/utils/airlock.d.ts +11 -0
  249. package/dist/utils/airlock.js +26 -0
  250. package/dist/utils/airlock.js.map +1 -0
  251. package/dist/utils/airlock.mjs +5 -0
  252. package/dist/utils/airlock.mjs.map +1 -0
  253. package/dist/utils/balanceDelta.d.mts +10 -0
  254. package/dist/utils/balanceDelta.d.ts +10 -0
  255. package/dist/utils/balanceDelta.js +12 -0
  256. package/dist/utils/balanceDelta.js.map +1 -0
  257. package/dist/utils/balanceDelta.mjs +3 -0
  258. package/dist/utils/balanceDelta.mjs.map +1 -0
  259. package/dist/utils/computeOptimalGamma.d.mts +7 -0
  260. package/dist/utils/computeOptimalGamma.d.ts +7 -0
  261. package/dist/utils/computeOptimalGamma.js +12 -0
  262. package/dist/utils/computeOptimalGamma.js.map +1 -0
  263. package/dist/utils/computeOptimalGamma.mjs +3 -0
  264. package/dist/utils/computeOptimalGamma.mjs.map +1 -0
  265. package/dist/utils/index.d.mts +11 -0
  266. package/dist/utils/index.d.ts +11 -0
  267. package/dist/utils/index.js +114 -24
  268. package/dist/utils/index.mjs +14 -4
  269. package/dist/utils/isToken0Expected.d.mts +13 -0
  270. package/dist/utils/isToken0Expected.d.ts +13 -0
  271. package/dist/utils/isToken0Expected.js +12 -0
  272. package/dist/utils/isToken0Expected.js.map +1 -0
  273. package/dist/utils/isToken0Expected.mjs +3 -0
  274. package/dist/utils/isToken0Expected.mjs.map +1 -0
  275. package/dist/utils/marketCapHelpers.d.mts +309 -0
  276. package/dist/utils/marketCapHelpers.d.ts +309 -0
  277. package/dist/utils/marketCapHelpers.js +54 -0
  278. package/dist/utils/marketCapHelpers.js.map +1 -0
  279. package/dist/utils/marketCapHelpers.mjs +5 -0
  280. package/dist/utils/marketCapHelpers.mjs.map +1 -0
  281. package/dist/utils/poolKey.d.mts +17 -0
  282. package/dist/utils/poolKey.d.ts +17 -0
  283. package/dist/utils/poolKey.js +12 -0
  284. package/dist/utils/poolKey.js.map +1 -0
  285. package/dist/utils/poolKey.mjs +3 -0
  286. package/dist/utils/poolKey.mjs.map +1 -0
  287. package/dist/utils/priceHelpers.d.mts +3 -3
  288. package/dist/utils/priceHelpers.d.ts +3 -3
  289. package/dist/utils/priceHelpers.js +10 -11
  290. package/dist/utils/priceHelpers.mjs +2 -3
  291. package/dist/utils/tickMath.d.mts +8 -1
  292. package/dist/utils/tickMath.d.ts +8 -1
  293. package/dist/utils/tickMath.js +17 -14
  294. package/dist/utils/tickMath.mjs +1 -2
  295. package/dist/utils/tokenAddressMiner.d.mts +30 -0
  296. package/dist/utils/tokenAddressMiner.d.ts +30 -0
  297. package/dist/utils/tokenAddressMiner.js +14 -0
  298. package/dist/utils/tokenAddressMiner.js.map +1 -0
  299. package/dist/utils/tokenAddressMiner.mjs +5 -0
  300. package/dist/utils/tokenAddressMiner.mjs.map +1 -0
  301. package/package.json +14 -11
  302. package/dist/__tests__/mocks/addresses.d.mts +0 -46
  303. package/dist/__tests__/mocks/addresses.d.ts +0 -46
  304. package/dist/__tests__/mocks/addresses.js +0 -53
  305. package/dist/__tests__/mocks/addresses.js.map +0 -1
  306. package/dist/__tests__/mocks/addresses.mjs +0 -44
  307. package/dist/__tests__/mocks/addresses.mjs.map +0 -1
  308. package/dist/__tests__/mocks/clients.d.mts +0 -22
  309. package/dist/__tests__/mocks/clients.d.ts +0 -22
  310. package/dist/__tests__/mocks/clients.js +0 -17036
  311. package/dist/__tests__/mocks/clients.js.map +0 -1
  312. package/dist/__tests__/mocks/clients.mjs +0 -17032
  313. package/dist/__tests__/mocks/clients.mjs.map +0 -1
  314. package/dist/chunk-2N5JZSZ4.js +0 -14
  315. package/dist/chunk-2N5JZSZ4.js.map +0 -1
  316. package/dist/chunk-4K5GBNQV.mjs.map +0 -1
  317. package/dist/chunk-7F5IXZLH.js +0 -308
  318. package/dist/chunk-7F5IXZLH.js.map +0 -1
  319. package/dist/chunk-7W72MFJO.mjs.map +0 -1
  320. package/dist/chunk-AQPINKEW.mjs.map +0 -1
  321. package/dist/chunk-AXA7YT2G.mjs.map +0 -1
  322. package/dist/chunk-AYPP5JEQ.mjs.map +0 -1
  323. package/dist/chunk-AZLFJNTG.mjs +0 -3
  324. package/dist/chunk-CIRZKWLL.js.map +0 -1
  325. package/dist/chunk-CIVGL27M.mjs +0 -160
  326. package/dist/chunk-CIVGL27M.mjs.map +0 -1
  327. package/dist/chunk-CYDWEPFL.mjs +0 -3
  328. package/dist/chunk-DCFHANLR.mjs.map +0 -1
  329. package/dist/chunk-DRBRT57F.js +0 -4
  330. package/dist/chunk-EFAPDN4J.js.map +0 -1
  331. package/dist/chunk-EIRVZJTT.js.map +0 -1
  332. package/dist/chunk-ER42VG7H.js.map +0 -1
  333. package/dist/chunk-FPGJKJIR.js +0 -872
  334. package/dist/chunk-FPGJKJIR.js.map +0 -1
  335. package/dist/chunk-HRFHDSNE.js +0 -180
  336. package/dist/chunk-HRFHDSNE.js.map +0 -1
  337. package/dist/chunk-IHBIBFZK.mjs +0 -12
  338. package/dist/chunk-IHBIBFZK.mjs.map +0 -1
  339. package/dist/chunk-JIDZBQ7R.mjs +0 -870
  340. package/dist/chunk-JIDZBQ7R.mjs.map +0 -1
  341. package/dist/chunk-KEXKKQVW.js +0 -42
  342. package/dist/chunk-KFD6U3LQ.mjs +0 -305
  343. package/dist/chunk-KFD6U3LQ.mjs.map +0 -1
  344. package/dist/chunk-KPBCG4X2.js.map +0 -1
  345. package/dist/chunk-KRN3ROUE.js +0 -4
  346. package/dist/chunk-KT7U37XS.mjs +0 -207
  347. package/dist/chunk-KT7U37XS.mjs.map +0 -1
  348. package/dist/chunk-LOROXNH3.mjs +0 -37
  349. package/dist/chunk-LOROXNH3.mjs.map +0 -1
  350. package/dist/chunk-LZO67TYV.mjs +0 -176
  351. package/dist/chunk-LZO67TYV.mjs.map +0 -1
  352. package/dist/chunk-MZ2UBC4M.mjs +0 -80
  353. package/dist/chunk-MZ2UBC4M.mjs.map +0 -1
  354. package/dist/chunk-OPKQMN46.mjs.map +0 -1
  355. package/dist/chunk-PMIJTXU6.js.map +0 -1
  356. package/dist/chunk-T644D54P.mjs.map +0 -1
  357. package/dist/chunk-TOMVBPNZ.js.map +0 -1
  358. package/dist/chunk-UHT4QLL7.js +0 -162
  359. package/dist/chunk-UHT4QLL7.js.map +0 -1
  360. package/dist/chunk-XG7K4R56.js.map +0 -1
  361. package/dist/chunk-YNP2HGJZ.js +0 -82
  362. package/dist/chunk-YNP2HGJZ.js.map +0 -1
  363. package/dist/chunk-ZAIP54LX.js +0 -209
  364. package/dist/chunk-ZAIP54LX.js.map +0 -1
  365. package/dist/magic-string.es-CBLXTCZP.js +0 -1304
  366. package/dist/magic-string.es-CBLXTCZP.js.map +0 -1
  367. package/dist/magic-string.es-QHA47FSB.mjs +0 -1298
  368. package/dist/magic-string.es-QHA47FSB.mjs.map +0 -1
@@ -0,0 +1,1706 @@
1
+ import { computeOptimalGamma } from './chunk-MNJ5OYPE.mjs';
2
+ import { isToken0Expected } from './chunk-NNNCVFOH.mjs';
3
+ import { MIN_TICK, MAX_TICK } from './chunk-KDT76YQE.mjs';
4
+ import { airlockAbi, bundlerAbi } from './chunk-OTG75GVH.mjs';
5
+ import { DEFAULT_V3_MAX_SHARE_TO_BE_SOLD, DEFAULT_V3_NUM_POSITIONS, DEFAULT_V4_YEARLY_MINT_RATE, DEFAULT_V3_INITIAL_VOTING_DELAY, DEFAULT_V3_INITIAL_VOTING_PERIOD, DEFAULT_V3_INITIAL_PROPOSAL_THRESHOLD, ZERO_ADDRESS, DEFAULT_CREATE_GAS_LIMIT, DEFAULT_PD_SLUGS, DEFAULT_V4_INITIAL_VOTING_DELAY, DEFAULT_V4_INITIAL_VOTING_PERIOD, DEFAULT_V4_INITIAL_PROPOSAL_THRESHOLD, TICK_SPACINGS, DEFAULT_V3_YEARLY_MINT_RATE, WAD, FLAG_MASK } from './chunk-QKO2FZGN.mjs';
6
+ import { getAddresses, CHAIN_IDS } from './chunk-AW3WR2D3.mjs';
7
+ import { DopplerBytecodeBaseMainnet, DopplerBytecode, DopplerDN404Bytecode, DERC20Bytecode } from './chunk-4TROGENW.mjs';
8
+ import { encodeAbiParameters, decodeEventLog, toHex, zeroAddress, keccak256, encodePacked, getAddress } from 'viem';
9
+
10
+ var MAX_UINT128 = (1n << 128n) - 1n;
11
+ var DopplerFactory = class {
12
+ constructor(publicClient, walletClient, chainId) {
13
+ this.multicurveBundlerSupport = /* @__PURE__ */ new Map();
14
+ this.publicClient = publicClient;
15
+ this.walletClient = walletClient;
16
+ this.chainId = chainId;
17
+ }
18
+ /**
19
+ * Set a custom migration data encoder function
20
+ * @param encoder Custom function to encode migration data
21
+ * @returns The factory instance for method chaining
22
+ */
23
+ withCustomMigrationEncoder(encoder) {
24
+ this.customMigrationEncoder = encoder;
25
+ return this;
26
+ }
27
+ async encodeCreateStaticAuctionParams(params) {
28
+ this.validateStaticAuctionParams(params);
29
+ const addresses = getAddresses(this.chainId);
30
+ const hasBeneficiaries = params.pool.beneficiaries && params.pool.beneficiaries.length > 0;
31
+ let poolInitializerData;
32
+ if (hasBeneficiaries) {
33
+ const sortedBeneficiaries = params.pool.beneficiaries.slice().sort((a, b) => {
34
+ const aAddr = a.beneficiary.toLowerCase();
35
+ const bAddr = b.beneficiary.toLowerCase();
36
+ return aAddr < bAddr ? -1 : aAddr > bAddr ? 1 : 0;
37
+ });
38
+ poolInitializerData = encodeAbiParameters(
39
+ [
40
+ {
41
+ type: "tuple",
42
+ components: [
43
+ { type: "uint24", name: "fee" },
44
+ { type: "int24", name: "tickLower" },
45
+ { type: "int24", name: "tickUpper" },
46
+ { type: "uint16", name: "numPositions" },
47
+ { type: "uint256", name: "maxShareToBeSold" },
48
+ {
49
+ type: "tuple[]",
50
+ name: "beneficiaries",
51
+ components: [
52
+ { type: "address", name: "beneficiary" },
53
+ { type: "uint96", name: "shares" }
54
+ ]
55
+ }
56
+ ]
57
+ }
58
+ ],
59
+ [{
60
+ fee: params.pool.fee,
61
+ tickLower: params.pool.startTick,
62
+ tickUpper: params.pool.endTick,
63
+ numPositions: params.pool.numPositions ?? DEFAULT_V3_NUM_POSITIONS,
64
+ maxShareToBeSold: params.pool.maxShareToBeSold ?? DEFAULT_V3_MAX_SHARE_TO_BE_SOLD,
65
+ beneficiaries: sortedBeneficiaries.map((b) => ({
66
+ beneficiary: b.beneficiary,
67
+ shares: b.shares
68
+ }))
69
+ }]
70
+ );
71
+ } else {
72
+ poolInitializerData = encodeAbiParameters(
73
+ [
74
+ {
75
+ type: "tuple",
76
+ components: [
77
+ { type: "uint24", name: "fee" },
78
+ { type: "int24", name: "tickLower" },
79
+ { type: "int24", name: "tickUpper" },
80
+ { type: "uint16", name: "numPositions" },
81
+ { type: "uint256", name: "maxShareToBeSold" }
82
+ ]
83
+ }
84
+ ],
85
+ [{
86
+ fee: params.pool.fee,
87
+ tickLower: params.pool.startTick,
88
+ tickUpper: params.pool.endTick,
89
+ numPositions: params.pool.numPositions ?? DEFAULT_V3_NUM_POSITIONS,
90
+ maxShareToBeSold: params.pool.maxShareToBeSold ?? DEFAULT_V3_MAX_SHARE_TO_BE_SOLD
91
+ }]
92
+ );
93
+ }
94
+ const liquidityMigratorData = this.encodeMigrationData(params.migration);
95
+ let tokenFactoryData;
96
+ if (this.isDoppler404Token(params.token)) {
97
+ const token404 = params.token;
98
+ const baseURI = token404.baseURI;
99
+ const unit = token404.unit !== void 0 ? BigInt(token404.unit) : 1000n;
100
+ tokenFactoryData = encodeAbiParameters(
101
+ [
102
+ { type: "string" },
103
+ { type: "string" },
104
+ { type: "string" },
105
+ { type: "uint256" }
106
+ ],
107
+ [
108
+ params.token.name,
109
+ params.token.symbol,
110
+ baseURI,
111
+ unit
112
+ ]
113
+ );
114
+ } else {
115
+ const tokenStd = params.token;
116
+ const vestingDuration = params.vesting?.duration ?? BigInt(0);
117
+ const yearlyMintRate = tokenStd.yearlyMintRate ?? DEFAULT_V4_YEARLY_MINT_RATE;
118
+ let vestingRecipients = [];
119
+ let vestingAmounts = [];
120
+ if (params.vesting) {
121
+ if (params.vesting.recipients && params.vesting.amounts) {
122
+ vestingRecipients = params.vesting.recipients;
123
+ vestingAmounts = params.vesting.amounts;
124
+ } else {
125
+ vestingRecipients = [params.userAddress];
126
+ vestingAmounts = [params.sale.initialSupply - params.sale.numTokensToSell];
127
+ }
128
+ }
129
+ tokenFactoryData = encodeAbiParameters(
130
+ [
131
+ { type: "string" },
132
+ { type: "string" },
133
+ { type: "uint256" },
134
+ { type: "uint256" },
135
+ { type: "address[]" },
136
+ { type: "uint256[]" },
137
+ { type: "string" }
138
+ ],
139
+ [
140
+ tokenStd.name,
141
+ tokenStd.symbol,
142
+ yearlyMintRate,
143
+ BigInt(vestingDuration),
144
+ vestingRecipients,
145
+ vestingAmounts,
146
+ tokenStd.tokenURI
147
+ ]
148
+ );
149
+ }
150
+ const useNoOpGovernance = params.governance.type === "noOp";
151
+ const governanceFactoryData = useNoOpGovernance ? "0x" : encodeAbiParameters(
152
+ [
153
+ { type: "string" },
154
+ { type: "uint48" },
155
+ { type: "uint32" },
156
+ { type: "uint256" }
157
+ ],
158
+ [
159
+ params.token.name,
160
+ params.governance.type === "custom" ? params.governance.initialVotingDelay : DEFAULT_V3_INITIAL_VOTING_DELAY,
161
+ params.governance.type === "custom" ? params.governance.initialVotingPeriod : DEFAULT_V3_INITIAL_VOTING_PERIOD,
162
+ params.governance.type === "custom" ? params.governance.initialProposalThreshold : DEFAULT_V3_INITIAL_PROPOSAL_THRESHOLD
163
+ ]
164
+ );
165
+ const governanceFactoryAddress = (() => {
166
+ if (useNoOpGovernance) {
167
+ const resolved2 = params.modules?.governanceFactory ?? (addresses.noOpGovernanceFactory ?? ZERO_ADDRESS);
168
+ if (!resolved2 || resolved2 === ZERO_ADDRESS) {
169
+ throw new Error("No-op governance requested, but no-op governanceFactory is not configured on this chain. Provide a governanceFactory override or use a supported chain.");
170
+ }
171
+ return resolved2;
172
+ }
173
+ const resolved = params.modules?.governanceFactory ?? addresses.governanceFactory;
174
+ if (!resolved || resolved === ZERO_ADDRESS) {
175
+ throw new Error("Standard governance requested but governanceFactory is not deployed on this chain.");
176
+ }
177
+ return resolved;
178
+ })();
179
+ const resolvedTokenFactory = params.modules?.tokenFactory ?? (this.isDoppler404Token(params.token) ? addresses.doppler404Factory : addresses.tokenFactory);
180
+ if (!resolvedTokenFactory || resolvedTokenFactory === ZERO_ADDRESS) {
181
+ throw new Error("Token factory address not configured. Provide an explicit address via builder.withTokenFactory(...) or ensure chain config includes a valid factory.");
182
+ }
183
+ const baseCreateParams = {
184
+ initialSupply: params.sale.initialSupply,
185
+ numTokensToSell: params.sale.numTokensToSell,
186
+ numeraire: params.sale.numeraire,
187
+ tokenFactory: resolvedTokenFactory,
188
+ tokenFactoryData,
189
+ governanceFactory: governanceFactoryAddress,
190
+ governanceFactoryData,
191
+ poolInitializer: (() => {
192
+ if (hasBeneficiaries) {
193
+ const lockableInitializer = params.modules?.lockableV3Initializer ?? addresses.lockableV3Initializer;
194
+ if (!lockableInitializer) {
195
+ throw new Error("Lockable V3 initializer address not configured on this chain. Required when using beneficiaries.");
196
+ }
197
+ return lockableInitializer;
198
+ }
199
+ return params.modules?.v3Initializer ?? addresses.v3Initializer;
200
+ })(),
201
+ poolInitializerData,
202
+ liquidityMigrator: this.getMigratorAddress(params.migration, params.modules),
203
+ liquidityMigratorData,
204
+ integrator: params.integrator ?? ZERO_ADDRESS
205
+ };
206
+ const minedCreateParams = await this.mineTokenOrder({
207
+ params,
208
+ baseCreateParams,
209
+ addresses
210
+ });
211
+ return minedCreateParams;
212
+ }
213
+ /**
214
+ * Simulate a static auction creation and return predicted addresses.
215
+ * Useful for pre-buy flows (bundle) to know the token/pool before sending.
216
+ */
217
+ async simulateCreateStaticAuction(params) {
218
+ const createParams = await this.encodeCreateStaticAuctionParams(params);
219
+ const addresses = getAddresses(this.chainId);
220
+ const airlockAddress = params.modules?.airlock ?? addresses.airlock;
221
+ const { request, result } = await this.publicClient.simulateContract({
222
+ address: airlockAddress,
223
+ abi: airlockAbi,
224
+ functionName: "create",
225
+ args: [{ ...createParams }],
226
+ account: this.walletClient?.account
227
+ });
228
+ const simResult = result;
229
+ const gasEstimate = await this.resolveCreateGasEstimate({
230
+ request,
231
+ address: airlockAddress,
232
+ createParams,
233
+ account: this.walletClient?.account ?? params.userAddress
234
+ });
235
+ if (!simResult || !Array.isArray(simResult) || simResult.length < 2) {
236
+ throw new Error("Failed to simulate static auction create");
237
+ }
238
+ return {
239
+ createParams,
240
+ asset: simResult[0],
241
+ pool: simResult[1],
242
+ gasEstimate,
243
+ execute: () => this.createStaticAuction(params, { _createParams: createParams })
244
+ };
245
+ }
246
+ /**
247
+ * Create a new static auction (using Uniswap V3 for initial liquidity)
248
+ * @param params Configuration for the static auction
249
+ * @returns The address of the created pool and token
250
+ */
251
+ async createStaticAuction(params, options) {
252
+ const createParams = options?._createParams ?? await this.encodeCreateStaticAuctionParams(params);
253
+ const addresses = getAddresses(this.chainId);
254
+ if (!this.walletClient) {
255
+ throw new Error("Wallet client required for write operations");
256
+ }
257
+ const airlockAddress = params.modules?.airlock ?? addresses.airlock;
258
+ const { request, result } = await this.publicClient.simulateContract({
259
+ address: airlockAddress,
260
+ abi: airlockAbi,
261
+ functionName: "create",
262
+ args: [{ ...createParams }],
263
+ account: this.walletClient.account
264
+ });
265
+ const simResult = result;
266
+ const gasEstimate = await this.resolveCreateGasEstimate({
267
+ request,
268
+ address: airlockAddress,
269
+ createParams,
270
+ account: this.walletClient.account
271
+ });
272
+ const gasOverride = params.gas ?? gasEstimate ?? DEFAULT_CREATE_GAS_LIMIT;
273
+ const hash = await this.walletClient.writeContract({ ...request, gas: gasOverride });
274
+ const receipt = await this.publicClient.waitForTransactionReceipt({ hash, confirmations: 2 });
275
+ if (simResult && Array.isArray(simResult) && simResult.length >= 2) {
276
+ return {
277
+ tokenAddress: simResult[0],
278
+ // asset
279
+ poolAddress: simResult[1],
280
+ // pool
281
+ transactionHash: hash
282
+ };
283
+ }
284
+ const createEvent = receipt.logs.find((log) => {
285
+ try {
286
+ const decoded = decodeEventLog({
287
+ abi: airlockAbi,
288
+ data: log.data,
289
+ topics: log.topics
290
+ });
291
+ return decoded.eventName === "Create";
292
+ } catch {
293
+ return false;
294
+ }
295
+ });
296
+ if (createEvent) {
297
+ const decoded = decodeEventLog({
298
+ abi: airlockAbi,
299
+ data: createEvent.data,
300
+ topics: createEvent.topics
301
+ });
302
+ if (decoded.eventName === "Create") {
303
+ return {
304
+ poolAddress: decoded.args.poolOrHook,
305
+ tokenAddress: decoded.args.asset,
306
+ transactionHash: hash
307
+ };
308
+ }
309
+ }
310
+ throw new Error("Failed to get pool and token addresses from transaction");
311
+ }
312
+ /**
313
+ * Generate a random salt based on user address
314
+ */
315
+ generateRandomSalt(account) {
316
+ const array = new Uint8Array(32);
317
+ if (typeof crypto !== "undefined" && crypto.getRandomValues) {
318
+ crypto.getRandomValues(array);
319
+ } else {
320
+ const timestamp = Date.now();
321
+ const timestampBytes = new Uint8Array(8);
322
+ for (let i = 0; i < 8; i++) {
323
+ timestampBytes[i] = timestamp >> i * 8 & 255;
324
+ }
325
+ for (let i = 0; i < 32; i++) {
326
+ if (i < 8) {
327
+ array[i] = timestampBytes[i];
328
+ } else {
329
+ array[i] = i;
330
+ }
331
+ }
332
+ }
333
+ if (account) {
334
+ const addressBytes = account.slice(2).padStart(40, "0");
335
+ for (let i = 0; i < 20; i++) {
336
+ const addressByte = parseInt(
337
+ addressBytes.slice(i * 2, (i + 1) * 2),
338
+ 16
339
+ );
340
+ array[i] ^= addressByte;
341
+ }
342
+ }
343
+ return `0x${Array.from(array).map((b) => b.toString(16).padStart(2, "0")).join("")}`;
344
+ }
345
+ /**
346
+ * Iteratively mine a salt that ensures the newly created token sorts after the numeraire.
347
+ * This mirrors the legacy SDK behaviour so tick configuration can assume the numeraire is token0.
348
+ */
349
+ async mineTokenOrder(args) {
350
+ const { params, baseCreateParams, addresses } = args;
351
+ const airlockAddress = params.modules?.airlock ?? addresses.airlock;
352
+ if (!airlockAddress || airlockAddress === ZERO_ADDRESS) {
353
+ throw new Error("Airlock address not configured. Provide an explicit address via modules.airlock or ensure chain config includes a valid airlock.");
354
+ }
355
+ const accountForSimulation = this.walletClient?.account ?? params.userAddress;
356
+ const numeraireBigInt = BigInt(params.sale.numeraire);
357
+ let attempt = 0n;
358
+ const maxAttempts = 256n;
359
+ let salt = this.generateRandomSalt(params.userAddress);
360
+ while (attempt < maxAttempts) {
361
+ const createParams = { ...baseCreateParams, salt };
362
+ const { result } = await this.publicClient.simulateContract({
363
+ address: airlockAddress,
364
+ abi: airlockAbi,
365
+ functionName: "create",
366
+ args: [{ ...createParams }],
367
+ account: accountForSimulation
368
+ });
369
+ const simResult = result;
370
+ if (!simResult || !Array.isArray(simResult) || simResult.length < 2) {
371
+ throw new Error("Failed to simulate static auction create while mining token ordering");
372
+ }
373
+ const tokenAddress = simResult[0];
374
+ if (BigInt(tokenAddress) > numeraireBigInt) {
375
+ return createParams;
376
+ }
377
+ attempt += 1n;
378
+ const incrementedAccount = toHex(BigInt(params.userAddress) + attempt);
379
+ salt = this.generateRandomSalt(incrementedAccount);
380
+ }
381
+ throw new Error("Token mining exceeded iteration limit while trying to force token order. Try again or provide a different user address.");
382
+ }
383
+ async encodeCreateDynamicAuctionParams(params) {
384
+ this.validateDynamicAuctionParams(params);
385
+ const addresses = getAddresses(this.chainId);
386
+ const gamma = params.auction.gamma ?? computeOptimalGamma(
387
+ params.auction.startTick,
388
+ params.auction.endTick,
389
+ params.auction.duration,
390
+ params.auction.epochLength,
391
+ params.pool.tickSpacing
392
+ );
393
+ let blockTimestamp;
394
+ if (params.blockTimestamp !== void 0) {
395
+ blockTimestamp = params.blockTimestamp;
396
+ } else {
397
+ const latestBlock = await this.publicClient.getBlock({ blockTag: "latest" });
398
+ blockTimestamp = Number(latestBlock.timestamp);
399
+ }
400
+ const startTimeOffset = params.startTimeOffset ?? 30;
401
+ const startTime = blockTimestamp + startTimeOffset;
402
+ const endTime = blockTimestamp + params.auction.duration + startTimeOffset;
403
+ const dopplerData = {
404
+ minimumProceeds: params.auction.minProceeds,
405
+ maximumProceeds: params.auction.maxProceeds,
406
+ startingTime: BigInt(startTime),
407
+ endingTime: BigInt(endTime),
408
+ startingTick: params.auction.startTick,
409
+ endingTick: params.auction.endTick,
410
+ epochLength: BigInt(params.auction.epochLength),
411
+ gamma,
412
+ isToken0: false,
413
+ // Will be determined during mining
414
+ numPDSlugs: BigInt(params.auction.numPdSlugs ?? DEFAULT_PD_SLUGS),
415
+ fee: params.pool.fee,
416
+ tickSpacing: params.pool.tickSpacing
417
+ };
418
+ if (this.isDoppler404Token(params.token)) {
419
+ if (!addresses.doppler404Factory || addresses.doppler404Factory === ZERO_ADDRESS) {
420
+ throw new Error("Doppler404 factory address not configured for this chain");
421
+ }
422
+ }
423
+ const vestingDuration = params.vesting?.duration ?? BigInt(0);
424
+ const tokenFactoryData = this.isDoppler404Token(params.token) ? (() => {
425
+ const t = params.token;
426
+ return {
427
+ name: t.name,
428
+ symbol: t.symbol,
429
+ baseURI: t.baseURI,
430
+ unit: t.unit !== void 0 ? BigInt(t.unit) : 1000n
431
+ };
432
+ })() : (() => {
433
+ const t = params.token;
434
+ let vestingRecipients = [];
435
+ let vestingAmounts = [];
436
+ if (params.vesting) {
437
+ if (params.vesting.recipients && params.vesting.amounts) {
438
+ vestingRecipients = params.vesting.recipients;
439
+ vestingAmounts = params.vesting.amounts;
440
+ } else {
441
+ vestingRecipients = [params.userAddress];
442
+ vestingAmounts = [params.sale.initialSupply - params.sale.numTokensToSell];
443
+ }
444
+ }
445
+ return {
446
+ name: t.name,
447
+ symbol: t.symbol,
448
+ initialSupply: params.sale.initialSupply,
449
+ airlock: addresses.airlock,
450
+ yearlyMintRate: t.yearlyMintRate ?? DEFAULT_V4_YEARLY_MINT_RATE,
451
+ vestingDuration: BigInt(vestingDuration),
452
+ recipients: vestingRecipients,
453
+ amounts: vestingAmounts,
454
+ tokenURI: t.tokenURI
455
+ };
456
+ })();
457
+ const resolvedTokenFactoryDyn = params.modules?.tokenFactory ?? (this.isDoppler404Token(params.token) ? addresses.doppler404Factory : addresses.tokenFactory);
458
+ if (!resolvedTokenFactoryDyn || resolvedTokenFactoryDyn === ZERO_ADDRESS) {
459
+ throw new Error("Token factory address not configured. Provide an explicit address via builder.withTokenFactory(...) or ensure chain config includes a valid factory.");
460
+ }
461
+ const [salt, hookAddress, tokenAddress, poolInitializerData, encodedTokenFactoryData] = this.mineHookAddress({
462
+ airlock: params.modules?.airlock ?? addresses.airlock,
463
+ poolManager: params.modules?.poolManager ?? addresses.poolManager,
464
+ deployer: params.modules?.dopplerDeployer ?? addresses.dopplerDeployer,
465
+ initialSupply: params.sale.initialSupply,
466
+ numTokensToSell: params.sale.numTokensToSell,
467
+ numeraire: params.sale.numeraire,
468
+ tokenFactory: resolvedTokenFactoryDyn,
469
+ tokenFactoryData,
470
+ poolInitializer: params.modules?.v4Initializer ?? addresses.v4Initializer,
471
+ poolInitializerData: dopplerData,
472
+ tokenVariant: this.isDoppler404Token(params.token) ? "doppler404" : "standard"
473
+ });
474
+ const liquidityMigratorData = this.encodeMigrationData(params.migration);
475
+ const useNoOpGovernance = params.governance.type === "noOp";
476
+ const governanceFactoryData = useNoOpGovernance ? "0x" : encodeAbiParameters(
477
+ [
478
+ { type: "string" },
479
+ { type: "uint48" },
480
+ { type: "uint32" },
481
+ { type: "uint256" }
482
+ ],
483
+ [
484
+ params.token.name,
485
+ params.governance.type === "custom" ? params.governance.initialVotingDelay : DEFAULT_V4_INITIAL_VOTING_DELAY,
486
+ params.governance.type === "custom" ? params.governance.initialVotingPeriod : DEFAULT_V4_INITIAL_VOTING_PERIOD,
487
+ params.governance.type === "custom" ? params.governance.initialProposalThreshold : DEFAULT_V4_INITIAL_PROPOSAL_THRESHOLD
488
+ ]
489
+ );
490
+ const governanceFactoryAddress = (() => {
491
+ if (useNoOpGovernance) {
492
+ const resolved2 = params.modules?.governanceFactory ?? (addresses.noOpGovernanceFactory ?? ZERO_ADDRESS);
493
+ if (!resolved2 || resolved2 === ZERO_ADDRESS) {
494
+ throw new Error("No-op governance requested, but no-op governanceFactory is not configured on this chain. Provide a governanceFactory override or use a supported chain.");
495
+ }
496
+ return resolved2;
497
+ }
498
+ const resolved = params.modules?.governanceFactory ?? addresses.governanceFactory;
499
+ if (!resolved || resolved === ZERO_ADDRESS) {
500
+ throw new Error("Standard governance requested but governanceFactory is not deployed on this chain.");
501
+ }
502
+ return resolved;
503
+ })();
504
+ const createParams = {
505
+ initialSupply: params.sale.initialSupply,
506
+ numTokensToSell: params.sale.numTokensToSell,
507
+ numeraire: params.sale.numeraire,
508
+ tokenFactory: resolvedTokenFactoryDyn,
509
+ tokenFactoryData: encodedTokenFactoryData,
510
+ governanceFactory: governanceFactoryAddress,
511
+ governanceFactoryData,
512
+ poolInitializer: params.modules?.v4Initializer ?? addresses.v4Initializer,
513
+ poolInitializerData,
514
+ liquidityMigrator: this.getMigratorAddress(params.migration, params.modules),
515
+ liquidityMigratorData,
516
+ integrator: params.integrator ?? ZERO_ADDRESS,
517
+ salt
518
+ };
519
+ return { createParams, hookAddress, tokenAddress };
520
+ }
521
+ /**
522
+ * Create a new dynamic auction (using Uniswap V4 hook for gradual Dutch auction)
523
+ * @param params Configuration for the dynamic auction
524
+ * @returns The address of the created hook and token
525
+ */
526
+ async createDynamicAuction(params, options) {
527
+ const addresses = getAddresses(this.chainId);
528
+ let createParams;
529
+ let hookAddress;
530
+ let tokenAddress;
531
+ if (options?._createParams) {
532
+ createParams = options._createParams;
533
+ } else {
534
+ const encoded = await this.encodeCreateDynamicAuctionParams(params);
535
+ createParams = encoded.createParams;
536
+ hookAddress = encoded.hookAddress;
537
+ tokenAddress = encoded.tokenAddress;
538
+ }
539
+ if (!this.walletClient) {
540
+ throw new Error("Wallet client required for write operations");
541
+ }
542
+ const airlockAddress = params.modules?.airlock ?? addresses.airlock;
543
+ const { request, result } = await this.publicClient.simulateContract({
544
+ address: airlockAddress,
545
+ abi: airlockAbi,
546
+ functionName: "create",
547
+ args: [{ ...createParams }],
548
+ account: this.walletClient.account
549
+ });
550
+ const simResult = result;
551
+ const gasEstimate = await this.resolveCreateGasEstimate({
552
+ request,
553
+ address: airlockAddress,
554
+ createParams,
555
+ account: this.walletClient.account
556
+ });
557
+ const gasOverride = params.gas ?? gasEstimate ?? DEFAULT_CREATE_GAS_LIMIT;
558
+ const hash = await this.walletClient.writeContract({ ...request, gas: gasOverride });
559
+ const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
560
+ let actualHookAddress = hookAddress ?? "";
561
+ let actualTokenAddress = tokenAddress ?? "";
562
+ if (simResult && Array.isArray(simResult) && simResult.length >= 2) {
563
+ actualTokenAddress = simResult[0];
564
+ actualHookAddress = simResult[1];
565
+ } else {
566
+ const createEvent = receipt.logs.find((log) => {
567
+ try {
568
+ const decoded = decodeEventLog({
569
+ abi: airlockAbi,
570
+ data: log.data,
571
+ topics: log.topics
572
+ });
573
+ return decoded.eventName === "Create";
574
+ } catch {
575
+ return false;
576
+ }
577
+ });
578
+ if (createEvent) {
579
+ const decoded = decodeEventLog({
580
+ abi: airlockAbi,
581
+ data: createEvent.data,
582
+ topics: createEvent.topics
583
+ });
584
+ if (decoded.eventName === "Create") {
585
+ actualHookAddress = decoded.args.poolOrHook;
586
+ actualTokenAddress = decoded.args.asset;
587
+ }
588
+ }
589
+ }
590
+ const poolId = this.computePoolId({
591
+ currency0: actualTokenAddress < params.sale.numeraire ? actualTokenAddress : params.sale.numeraire,
592
+ currency1: actualTokenAddress < params.sale.numeraire ? params.sale.numeraire : actualTokenAddress,
593
+ fee: params.pool.fee,
594
+ tickSpacing: params.pool.tickSpacing,
595
+ hooks: actualHookAddress
596
+ });
597
+ return {
598
+ hookAddress: actualHookAddress,
599
+ tokenAddress: actualTokenAddress,
600
+ poolId,
601
+ transactionHash: hash
602
+ };
603
+ }
604
+ /**
605
+ * Simulate a dynamic auction creation and return predicted addresses and poolId.
606
+ * Useful for clients that need the hook/token/poolId before submitting the tx.
607
+ */
608
+ async simulateCreateDynamicAuction(params) {
609
+ const { createParams } = await this.encodeCreateDynamicAuctionParams(params);
610
+ const addresses = getAddresses(this.chainId);
611
+ const airlockAddress = params.modules?.airlock ?? addresses.airlock;
612
+ const { request, result } = await this.publicClient.simulateContract({
613
+ address: airlockAddress,
614
+ abi: airlockAbi,
615
+ functionName: "create",
616
+ args: [{ ...createParams }],
617
+ account: this.walletClient?.account
618
+ });
619
+ const simResult = result;
620
+ const gasEstimate = await this.resolveCreateGasEstimate({
621
+ request,
622
+ address: airlockAddress,
623
+ createParams,
624
+ account: this.walletClient?.account ?? params.userAddress
625
+ });
626
+ if (!simResult || !Array.isArray(simResult) || simResult.length < 2) {
627
+ throw new Error("Failed to simulate dynamic auction create");
628
+ }
629
+ const tokenAddress = simResult[0];
630
+ const hookAddress = simResult[1];
631
+ const poolId = this.computePoolId({
632
+ currency0: tokenAddress < params.sale.numeraire ? tokenAddress : params.sale.numeraire,
633
+ currency1: tokenAddress < params.sale.numeraire ? params.sale.numeraire : tokenAddress,
634
+ fee: params.pool.fee,
635
+ tickSpacing: params.pool.tickSpacing,
636
+ hooks: hookAddress
637
+ });
638
+ return {
639
+ createParams,
640
+ hookAddress,
641
+ tokenAddress,
642
+ poolId,
643
+ gasEstimate,
644
+ execute: () => this.createDynamicAuction(params, { _createParams: createParams })
645
+ };
646
+ }
647
+ async resolveCreateGasEstimate(args) {
648
+ const { request, address, createParams, account } = args;
649
+ const gasFromRequest = request && typeof request === "object" && "gas" in request ? request.gas : void 0;
650
+ if (gasFromRequest) {
651
+ return gasFromRequest;
652
+ }
653
+ try {
654
+ const estimated = await this.publicClient.estimateContractGas({
655
+ address,
656
+ abi: airlockAbi,
657
+ functionName: "create",
658
+ args: [{ ...createParams }],
659
+ account
660
+ });
661
+ return estimated;
662
+ } catch {
663
+ return void 0;
664
+ }
665
+ }
666
+ isDoppler404Token(token) {
667
+ return token.type === "doppler404";
668
+ }
669
+ /**
670
+ * Encode migration data based on the MigrationConfig
671
+ * This replaces the manual encoding methods from the old SDKs
672
+ */
673
+ encodeMigrationData(config) {
674
+ if (this.customMigrationEncoder) {
675
+ return this.customMigrationEncoder(config);
676
+ }
677
+ switch (config.type) {
678
+ case "uniswapV2":
679
+ return "0x";
680
+ case "noOp":
681
+ return "0x";
682
+ case "uniswapV3":
683
+ const expectedSpacing = TICK_SPACINGS[config.fee];
684
+ if (expectedSpacing !== void 0 && config.tickSpacing === expectedSpacing) {
685
+ return "0x";
686
+ }
687
+ return encodeAbiParameters(
688
+ [
689
+ { type: "uint24" },
690
+ // fee
691
+ { type: "int24" }
692
+ // tickSpacing
693
+ ],
694
+ [config.fee, config.tickSpacing]
695
+ );
696
+ case "uniswapV4":
697
+ const streamableFees = config.streamableFees;
698
+ if (!streamableFees) {
699
+ return "0x";
700
+ }
701
+ const beneficiaryData = [...streamableFees.beneficiaries].sort((a, b) => {
702
+ const addrA = a.beneficiary.toLowerCase();
703
+ const addrB = b.beneficiary.toLowerCase();
704
+ return addrA < addrB ? -1 : addrA > addrB ? 1 : 0;
705
+ });
706
+ return encodeAbiParameters(
707
+ [
708
+ { type: "uint24" },
709
+ // fee
710
+ { type: "int24" },
711
+ // tickSpacing
712
+ { type: "uint32" },
713
+ // lockDuration (0 if no streamableFees)
714
+ {
715
+ type: "tuple[]",
716
+ components: [
717
+ { type: "address", name: "beneficiary" },
718
+ { type: "uint96", name: "shares" }
719
+ ]
720
+ }
721
+ ],
722
+ [
723
+ config.fee,
724
+ config.tickSpacing,
725
+ streamableFees.lockDuration,
726
+ beneficiaryData
727
+ ]
728
+ );
729
+ default:
730
+ throw new Error("Unknown migration type");
731
+ }
732
+ }
733
+ /**
734
+ * Encode create params for Uniswap V4 Multicurve initializer/migrator flow
735
+ */
736
+ encodeCreateMulticurveParams(params) {
737
+ if (!params.pool || params.pool.curves.length === 0) {
738
+ throw new Error("Multicurve pool must include at least one curve");
739
+ }
740
+ const normalizedCurves = this.normalizeMulticurveCurves(params.pool.curves, params.pool.tickSpacing);
741
+ const addresses = getAddresses(this.chainId);
742
+ const sortedBeneficiaries = (params.pool.beneficiaries ?? []).slice().sort((a, b) => {
743
+ const aAddr = a.beneficiary.toLowerCase();
744
+ const bAddr = b.beneficiary.toLowerCase();
745
+ return aAddr < bAddr ? -1 : aAddr > bAddr ? 1 : 0;
746
+ });
747
+ const useScheduledInitializer = params.schedule !== void 0;
748
+ let scheduleStartTime;
749
+ if (useScheduledInitializer) {
750
+ scheduleStartTime = Number(params.schedule.startTime);
751
+ if (!Number.isFinite(scheduleStartTime) || !Number.isInteger(scheduleStartTime)) {
752
+ throw new Error("Scheduled multicurve startTime must be an integer number of seconds since Unix epoch");
753
+ }
754
+ if (scheduleStartTime < 0) {
755
+ throw new Error("Scheduled multicurve startTime cannot be negative");
756
+ }
757
+ const UINT32_MAX = 4294967295;
758
+ if (scheduleStartTime > UINT32_MAX) {
759
+ throw new Error("Scheduled multicurve startTime must fit within uint32 (seconds since Unix epoch up to year 2106)");
760
+ }
761
+ }
762
+ const poolInitializerTupleComponents = [
763
+ { name: "fee", type: "uint24" },
764
+ { name: "tickSpacing", type: "int24" },
765
+ {
766
+ name: "curves",
767
+ type: "tuple[]",
768
+ components: [
769
+ { type: "int24", name: "tickLower" },
770
+ { type: "int24", name: "tickUpper" },
771
+ { type: "uint16", name: "numPositions" },
772
+ { type: "uint256", name: "shares" }
773
+ ]
774
+ },
775
+ {
776
+ name: "beneficiaries",
777
+ type: "tuple[]",
778
+ components: [
779
+ { type: "address", name: "beneficiary" },
780
+ { type: "uint96", name: "shares" }
781
+ ]
782
+ }
783
+ ];
784
+ if (useScheduledInitializer) {
785
+ poolInitializerTupleComponents.push({ name: "startingTime", type: "uint32" });
786
+ }
787
+ const baseInitializerParams = {
788
+ fee: params.pool.fee,
789
+ tickSpacing: params.pool.tickSpacing,
790
+ curves: normalizedCurves.map((c) => ({
791
+ tickLower: c.tickLower,
792
+ tickUpper: c.tickUpper,
793
+ numPositions: c.numPositions,
794
+ shares: c.shares
795
+ })),
796
+ beneficiaries: sortedBeneficiaries.map((b) => ({
797
+ beneficiary: b.beneficiary,
798
+ shares: b.shares
799
+ }))
800
+ };
801
+ const poolInitializerValue = useScheduledInitializer ? { ...baseInitializerParams, startingTime: scheduleStartTime } : baseInitializerParams;
802
+ const poolInitializerData = encodeAbiParameters(
803
+ [{ type: "tuple", components: poolInitializerTupleComponents }],
804
+ [poolInitializerValue]
805
+ );
806
+ let tokenFactoryData;
807
+ if (this.isDoppler404Token(params.token)) {
808
+ const token404 = params.token;
809
+ const unit = token404.unit !== void 0 ? BigInt(token404.unit) : 1000n;
810
+ tokenFactoryData = encodeAbiParameters(
811
+ [{ type: "string" }, { type: "string" }, { type: "string" }, { type: "uint256" }],
812
+ [token404.name, token404.symbol, token404.baseURI, unit]
813
+ );
814
+ } else {
815
+ const tokenStd = params.token;
816
+ const vestingDuration = params.vesting?.duration ?? BigInt(0);
817
+ const yearlyMintRate = tokenStd.yearlyMintRate ?? DEFAULT_V3_YEARLY_MINT_RATE;
818
+ let vestingRecipients = [];
819
+ let vestingAmounts = [];
820
+ if (params.vesting) {
821
+ if (params.vesting.recipients && params.vesting.amounts) {
822
+ vestingRecipients = params.vesting.recipients;
823
+ vestingAmounts = params.vesting.amounts;
824
+ } else {
825
+ vestingRecipients = [params.userAddress];
826
+ vestingAmounts = [params.sale.initialSupply - params.sale.numTokensToSell];
827
+ }
828
+ }
829
+ tokenFactoryData = encodeAbiParameters(
830
+ [{ type: "string" }, { type: "string" }, { type: "uint256" }, { type: "uint256" }, { type: "address[]" }, { type: "uint256[]" }, { type: "string" }],
831
+ [tokenStd.name, tokenStd.symbol, yearlyMintRate, BigInt(vestingDuration), vestingRecipients, vestingAmounts, tokenStd.tokenURI]
832
+ );
833
+ }
834
+ const useNoOpGovernance = params.governance.type === "noOp";
835
+ const governanceFactoryData = useNoOpGovernance ? "0x" : encodeAbiParameters(
836
+ [{ type: "string" }, { type: "uint48" }, { type: "uint32" }, { type: "uint256" }],
837
+ [
838
+ params.token.name,
839
+ params.governance.type === "custom" ? params.governance.initialVotingDelay : DEFAULT_V4_INITIAL_VOTING_DELAY,
840
+ params.governance.type === "custom" ? params.governance.initialVotingPeriod : DEFAULT_V4_INITIAL_VOTING_PERIOD,
841
+ params.governance.type === "custom" ? params.governance.initialProposalThreshold : DEFAULT_V4_INITIAL_PROPOSAL_THRESHOLD
842
+ ]
843
+ );
844
+ const salt = this.generateRandomSalt(params.userAddress);
845
+ const resolvedTokenFactory = params.modules?.tokenFactory ?? (this.isDoppler404Token(params.token) ? addresses.doppler404Factory : addresses.tokenFactory);
846
+ if (!resolvedTokenFactory || resolvedTokenFactory === ZERO_ADDRESS) {
847
+ throw new Error("Token factory address not configured. Provide an explicit address or ensure chain config includes a valid factory.");
848
+ }
849
+ const resolvedInitializer = (() => {
850
+ if (useScheduledInitializer) {
851
+ return params.modules?.v4ScheduledMulticurveInitializer ?? addresses.v4ScheduledMulticurveInitializer;
852
+ }
853
+ return params.modules?.v4MulticurveInitializer ?? addresses.v4MulticurveInitializer;
854
+ })();
855
+ if (!resolvedInitializer || resolvedInitializer === ZERO_ADDRESS) {
856
+ throw new Error(
857
+ useScheduledInitializer ? "Scheduled multicurve initializer address not configured on this chain. Override via builder or update chain config." : "Multicurve initializer address not configured on this chain. Override via builder or update chain config."
858
+ );
859
+ }
860
+ const hasBeneficiaries = params.pool.beneficiaries && params.pool.beneficiaries.length > 0;
861
+ let liquidityMigratorData;
862
+ let resolvedMigrator;
863
+ if (hasBeneficiaries) {
864
+ liquidityMigratorData = "0x";
865
+ resolvedMigrator = params.modules?.noOpMigrator ?? addresses.noOpMigrator;
866
+ if (!resolvedMigrator || resolvedMigrator === ZERO_ADDRESS) {
867
+ throw new Error("NoOpMigrator address not configured on this chain. Override via modules.noOpMigrator or update chain config.");
868
+ }
869
+ } else {
870
+ liquidityMigratorData = this.encodeMigrationData(params.migration);
871
+ resolvedMigrator = this.getMigratorAddress(params.migration, params.modules);
872
+ if (!resolvedMigrator || resolvedMigrator === ZERO_ADDRESS) {
873
+ throw new Error("Migrator address not configured on this chain. Override via builder or update chain config.");
874
+ }
875
+ }
876
+ const governanceFactoryAddress = (() => {
877
+ if (useNoOpGovernance) {
878
+ const resolved2 = params.modules?.governanceFactory ?? (addresses.noOpGovernanceFactory ?? ZERO_ADDRESS);
879
+ if (!resolved2 || resolved2 === ZERO_ADDRESS) {
880
+ throw new Error("No-op governance requested, but no-op governanceFactory is not configured on this chain.");
881
+ }
882
+ return resolved2;
883
+ }
884
+ const resolved = params.modules?.governanceFactory ?? addresses.governanceFactory;
885
+ if (!resolved || resolved === ZERO_ADDRESS) {
886
+ throw new Error("Standard governance requested but governanceFactory is not deployed on this chain.");
887
+ }
888
+ return resolved;
889
+ })();
890
+ const createParams = {
891
+ initialSupply: params.sale.initialSupply,
892
+ numTokensToSell: params.sale.numTokensToSell,
893
+ numeraire: params.sale.numeraire,
894
+ tokenFactory: resolvedTokenFactory,
895
+ tokenFactoryData,
896
+ governanceFactory: governanceFactoryAddress,
897
+ governanceFactoryData,
898
+ poolInitializer: resolvedInitializer,
899
+ poolInitializerData,
900
+ liquidityMigrator: resolvedMigrator,
901
+ liquidityMigratorData,
902
+ integrator: params.integrator ?? ZERO_ADDRESS,
903
+ salt
904
+ };
905
+ return createParams;
906
+ }
907
+ async simulateCreateMulticurve(params) {
908
+ const createParams = this.encodeCreateMulticurveParams(params);
909
+ const addresses = getAddresses(this.chainId);
910
+ const airlockAddress = params.modules?.airlock ?? addresses.airlock;
911
+ const { request, result } = await this.publicClient.simulateContract({
912
+ address: airlockAddress,
913
+ abi: airlockAbi,
914
+ functionName: "create",
915
+ args: [{ ...createParams }],
916
+ account: this.walletClient?.account
917
+ });
918
+ const simResult = result;
919
+ const gasEstimate = await this.resolveCreateGasEstimate({
920
+ request,
921
+ address: airlockAddress,
922
+ createParams,
923
+ account: this.walletClient?.account ?? params.userAddress
924
+ });
925
+ if (!simResult || !Array.isArray(simResult) || simResult.length < 2) {
926
+ throw new Error("Failed to simulate multicurve create");
927
+ }
928
+ return {
929
+ createParams,
930
+ asset: simResult[0],
931
+ pool: simResult[1],
932
+ gasEstimate,
933
+ execute: () => this.createMulticurve(params, { _createParams: createParams })
934
+ };
935
+ }
936
+ async createMulticurve(params, options) {
937
+ const createParams = options?._createParams ?? this.encodeCreateMulticurveParams(params);
938
+ const addresses = getAddresses(this.chainId);
939
+ if (!this.walletClient) throw new Error("Wallet client required for write operations");
940
+ const airlockAddress = params.modules?.airlock ?? addresses.airlock;
941
+ const { request, result } = await this.publicClient.simulateContract({
942
+ address: airlockAddress,
943
+ abi: airlockAbi,
944
+ functionName: "create",
945
+ args: [{ ...createParams }],
946
+ account: this.walletClient.account
947
+ });
948
+ const simResult = result;
949
+ const gasEstimate = await this.resolveCreateGasEstimate({
950
+ request,
951
+ address: airlockAddress,
952
+ createParams,
953
+ account: this.walletClient.account
954
+ });
955
+ const gas = params.gas ?? gasEstimate ?? DEFAULT_CREATE_GAS_LIMIT;
956
+ const hash = await this.walletClient.writeContract({ ...request, gas });
957
+ await this.publicClient.waitForTransactionReceipt({ hash, confirmations: 2 });
958
+ if (simResult && Array.isArray(simResult) && simResult.length >= 2) {
959
+ return { tokenAddress: simResult[0], poolAddress: simResult[1], transactionHash: hash };
960
+ }
961
+ throw new Error("Failed to get pool/token addresses from multicurve create");
962
+ }
963
+ /**
964
+ * Normalize user-provided multicurve positions and ensure they satisfy SDK constraints
965
+ */
966
+ normalizeMulticurveCurves(curves, tickSpacing) {
967
+ if (tickSpacing <= 0) {
968
+ throw new Error("Tick spacing must be positive");
969
+ }
970
+ if (!curves.length) {
971
+ throw new Error("Multicurve pool must include at least one curve");
972
+ }
973
+ let totalShares = 0n;
974
+ let mostPositiveTickUpper;
975
+ const sanitizedCurves = curves.map((curve) => {
976
+ const sanitized = { ...curve };
977
+ if (!Number.isFinite(sanitized.tickLower) || !Number.isFinite(sanitized.tickUpper)) {
978
+ throw new Error("Multicurve ticks must be finite numbers");
979
+ }
980
+ if (sanitized.tickLower >= sanitized.tickUpper) {
981
+ throw new Error("Multicurve curve tickLower must be less than tickUpper");
982
+ }
983
+ if (sanitized.tickLower <= 0 || sanitized.tickUpper <= 0) {
984
+ console.warn("Warning: Using negative or zero ticks in multicurve configuration. Please verify this is intentional before proceeding.");
985
+ }
986
+ if (!Number.isInteger(sanitized.numPositions) || sanitized.numPositions <= 0) {
987
+ throw new Error("Multicurve curve numPositions must be a positive integer");
988
+ }
989
+ if (sanitized.shares <= 0n) {
990
+ throw new Error("Multicurve curve shares must be positive");
991
+ }
992
+ totalShares += sanitized.shares;
993
+ if (totalShares > WAD) {
994
+ throw new Error("Total multicurve shares cannot exceed 100% (1e18)");
995
+ }
996
+ if (mostPositiveTickUpper === void 0 || sanitized.tickUpper > mostPositiveTickUpper) {
997
+ mostPositiveTickUpper = sanitized.tickUpper;
998
+ }
999
+ return sanitized;
1000
+ });
1001
+ if (totalShares === WAD) {
1002
+ return sanitizedCurves;
1003
+ }
1004
+ const missingShare = WAD - totalShares;
1005
+ if (missingShare <= 0n) {
1006
+ return sanitizedCurves;
1007
+ }
1008
+ const fallbackTickLower = mostPositiveTickUpper;
1009
+ if (fallbackTickLower === void 0) {
1010
+ throw new Error("Unable to determine fallback multicurve tick range");
1011
+ }
1012
+ const fallbackTickUpper = this.roundMaxTickDown(tickSpacing);
1013
+ const fallbackCurve = {
1014
+ // Extend from the most positive user tick out to the maximum supported tick bucket
1015
+ tickLower: fallbackTickLower,
1016
+ tickUpper: fallbackTickUpper,
1017
+ numPositions: sanitizedCurves[sanitizedCurves.length - 1]?.numPositions ?? 1,
1018
+ shares: missingShare
1019
+ };
1020
+ return [...sanitizedCurves, fallbackCurve];
1021
+ }
1022
+ roundMaxTickDown(tickSpacing) {
1023
+ if (tickSpacing <= 0) {
1024
+ throw new Error("Tick spacing must be positive");
1025
+ }
1026
+ const rounded = Math.floor(MAX_TICK / tickSpacing) * tickSpacing;
1027
+ return rounded;
1028
+ }
1029
+ validateStaticAuctionParams(params) {
1030
+ if (!params.token.name || params.token.name.trim().length === 0) {
1031
+ throw new Error("Token name is required");
1032
+ }
1033
+ if (!params.token.symbol || params.token.symbol.trim().length === 0) {
1034
+ throw new Error("Token symbol is required");
1035
+ }
1036
+ if (params.pool.startTick >= params.pool.endTick) {
1037
+ throw new Error("Start tick must be less than end tick");
1038
+ }
1039
+ const tickSpacing = TICK_SPACINGS[params.pool.fee];
1040
+ if (tickSpacing === void 0) {
1041
+ throw new Error(`Unsupported fee tier ${params.pool.fee} for static auctions`);
1042
+ }
1043
+ if (params.pool.startTick < MIN_TICK || params.pool.endTick > MAX_TICK) {
1044
+ throw new Error(`Ticks must be within the allowed range (${MIN_TICK} to ${MAX_TICK})`);
1045
+ }
1046
+ const startTickAligned = params.pool.startTick % tickSpacing === 0;
1047
+ const endTickAligned = params.pool.endTick % tickSpacing === 0;
1048
+ if (!startTickAligned || !endTickAligned) {
1049
+ throw new Error(`Pool ticks must be multiples of tick spacing ${tickSpacing} for fee tier ${params.pool.fee}`);
1050
+ }
1051
+ if (params.sale.initialSupply <= BigInt(0)) {
1052
+ throw new Error("Initial supply must be positive");
1053
+ }
1054
+ if (params.sale.numTokensToSell <= BigInt(0)) {
1055
+ throw new Error("Number of tokens to sell must be positive");
1056
+ }
1057
+ if (params.sale.numTokensToSell > params.sale.initialSupply) {
1058
+ throw new Error("Cannot sell more tokens than initial supply");
1059
+ }
1060
+ if (params.vesting) {
1061
+ if (params.vesting.recipients && params.vesting.amounts) {
1062
+ if (params.vesting.recipients.length !== params.vesting.amounts.length) {
1063
+ throw new Error("Vesting recipients and amounts arrays must have the same length");
1064
+ }
1065
+ if (params.vesting.recipients.length === 0) {
1066
+ throw new Error("Vesting recipients array cannot be empty");
1067
+ }
1068
+ const totalVested = params.vesting.amounts.reduce((sum, amt) => sum + amt, BigInt(0));
1069
+ const availableForVesting = params.sale.initialSupply - params.sale.numTokensToSell;
1070
+ if (totalVested > availableForVesting) {
1071
+ throw new Error(`Total vesting amount (${totalVested}) exceeds available tokens (${availableForVesting})`);
1072
+ }
1073
+ } else {
1074
+ const vestedAmount = params.sale.initialSupply - params.sale.numTokensToSell;
1075
+ if (vestedAmount <= BigInt(0)) {
1076
+ throw new Error("No tokens available for vesting");
1077
+ }
1078
+ }
1079
+ }
1080
+ if (params.migration.type === "uniswapV4" && params.migration.streamableFees) {
1081
+ const beneficiaries = params.migration.streamableFees.beneficiaries;
1082
+ if (beneficiaries.length === 0) {
1083
+ throw new Error("At least one beneficiary is required for V4 migration");
1084
+ }
1085
+ const totalShares = beneficiaries.reduce((sum, b) => sum + b.shares, 0n);
1086
+ if (totalShares !== WAD) {
1087
+ throw new Error(`Beneficiary shares must sum to ${WAD} (100%), but got ${totalShares}`);
1088
+ }
1089
+ }
1090
+ if (params.pool.beneficiaries && params.pool.beneficiaries.length > 0) {
1091
+ const beneficiaries = params.pool.beneficiaries;
1092
+ const totalShares = beneficiaries.reduce((sum, b) => sum + b.shares, 0n);
1093
+ if (totalShares !== WAD) {
1094
+ throw new Error(`Pool beneficiary shares must sum to ${WAD} (100%), but got ${totalShares}`);
1095
+ }
1096
+ for (const b of beneficiaries) {
1097
+ if (b.shares <= 0n) {
1098
+ throw new Error("Each beneficiary must have positive shares");
1099
+ }
1100
+ }
1101
+ }
1102
+ }
1103
+ /**
1104
+ * Validate dynamic auction parameters
1105
+ */
1106
+ validateDynamicAuctionParams(params) {
1107
+ if (!params.token.name || params.token.name.trim().length === 0) {
1108
+ throw new Error("Token name is required");
1109
+ }
1110
+ if (!params.token.symbol || params.token.symbol.trim().length === 0) {
1111
+ throw new Error("Token symbol is required");
1112
+ }
1113
+ const isToken0 = isToken0Expected(params.sale.numeraire);
1114
+ if (isToken0 && params.auction.startTick <= params.auction.endTick) {
1115
+ throw new Error("Start tick must be greater than end tick if base token is currency0");
1116
+ }
1117
+ if (!isToken0 && params.auction.startTick >= params.auction.endTick) {
1118
+ throw new Error("Start tick must be less than end tick if base token is currency1");
1119
+ }
1120
+ if (params.sale.initialSupply <= BigInt(0)) {
1121
+ throw new Error("Initial supply must be positive");
1122
+ }
1123
+ if (params.sale.numTokensToSell <= BigInt(0)) {
1124
+ throw new Error("Number of tokens to sell must be positive");
1125
+ }
1126
+ if (params.sale.numTokensToSell > params.sale.initialSupply) {
1127
+ throw new Error("Cannot sell more tokens than initial supply");
1128
+ }
1129
+ if (params.auction.duration <= 0) {
1130
+ throw new Error("Auction duration must be positive");
1131
+ }
1132
+ if (params.auction.epochLength <= 0) {
1133
+ throw new Error("Epoch length must be positive");
1134
+ }
1135
+ if (params.pool.tickSpacing <= 0) {
1136
+ throw new Error("Tick spacing must be positive");
1137
+ }
1138
+ if (params.auction.duration % params.auction.epochLength !== 0) {
1139
+ throw new Error("Epoch length must divide total duration evenly");
1140
+ }
1141
+ if (params.auction.gamma !== void 0) {
1142
+ if (params.auction.gamma % params.pool.tickSpacing !== 0) {
1143
+ throw new Error("Gamma must be divisible by tick spacing");
1144
+ }
1145
+ }
1146
+ if (params.migration.type === "uniswapV4" && params.migration.streamableFees) {
1147
+ const beneficiaries = params.migration.streamableFees.beneficiaries;
1148
+ if (beneficiaries.length === 0) {
1149
+ throw new Error("At least one beneficiary is required for V4 migration");
1150
+ }
1151
+ const totalShares = beneficiaries.reduce((sum, b) => sum + b.shares, 0n);
1152
+ if (totalShares !== WAD) {
1153
+ throw new Error(`Beneficiary shares must sum to ${WAD} (100%), but got ${totalShares}`);
1154
+ }
1155
+ }
1156
+ }
1157
+ /**
1158
+ * Get the airlock contract address for the current chain
1159
+ */
1160
+ getAirlockAddress() {
1161
+ const addresses = getAddresses(this.chainId);
1162
+ return addresses.airlock;
1163
+ }
1164
+ /**
1165
+ * Get the appropriate initializer address based on auction type
1166
+ */
1167
+ getInitializerAddress(isStatic) {
1168
+ const addresses = getAddresses(this.chainId);
1169
+ return isStatic ? addresses.v3Initializer : addresses.v4Initializer;
1170
+ }
1171
+ /**
1172
+ * Get the Bundler contract address for the current chain
1173
+ * Used to perform atomic create + swap ("bundle") flows for static auctions
1174
+ */
1175
+ getBundlerAddress() {
1176
+ const addresses = getAddresses(this.chainId);
1177
+ const addr = addresses.bundler;
1178
+ if (!addr || addr === zeroAddress) {
1179
+ throw new Error("Bundler address not configured for this chain");
1180
+ }
1181
+ return addr;
1182
+ }
1183
+ /**
1184
+ * Get the appropriate migrator address based on migration config
1185
+ * Allows override via ModuleAddressOverrides when provided in params.
1186
+ */
1187
+ getMigratorAddress(config, overrides) {
1188
+ const addresses = getAddresses(this.chainId);
1189
+ switch (config.type) {
1190
+ case "uniswapV2":
1191
+ return overrides?.v2Migrator ?? addresses.v2Migrator;
1192
+ case "uniswapV3":
1193
+ return overrides?.v3Migrator ?? addresses.v3Migrator;
1194
+ case "uniswapV4":
1195
+ return overrides?.v4Migrator ?? addresses.v4Migrator;
1196
+ case "noOp": {
1197
+ const noOpAddress = overrides?.noOpMigrator ?? addresses.noOpMigrator;
1198
+ if (!noOpAddress) {
1199
+ throw new Error("NoOpMigrator not configured on this chain. Provide override via modules.noOpMigrator or update chain config.");
1200
+ }
1201
+ return noOpAddress;
1202
+ }
1203
+ default:
1204
+ throw new Error("Unknown migration type");
1205
+ }
1206
+ }
1207
+ // computeTicks moved to builders. No longer needed here.
1208
+ // computeOptimalGamma moved to utils.
1209
+ // -----------------------------
1210
+ // Bundler helpers (Static/V3)
1211
+ // -----------------------------
1212
+ /**
1213
+ * Simulate a bundle with exact input on Uniswap V3 as part of create
1214
+ * Returns the expected output amount for the provided exact input.
1215
+ */
1216
+ async simulateBundleExactInput(createParams, params) {
1217
+ const bundler = this.getBundlerAddress();
1218
+ const { result } = await this.publicClient.simulateContract({
1219
+ address: bundler,
1220
+ abi: bundlerAbi,
1221
+ functionName: "simulateBundleExactIn",
1222
+ args: [
1223
+ { ...createParams },
1224
+ {
1225
+ tokenIn: params.tokenIn,
1226
+ tokenOut: params.tokenOut,
1227
+ amountIn: params.amountIn,
1228
+ fee: params.fee,
1229
+ sqrtPriceLimitX96: params.sqrtPriceLimitX96
1230
+ }
1231
+ ]
1232
+ });
1233
+ return result;
1234
+ }
1235
+ /**
1236
+ * Simulate a bundle with exact output on Uniswap V3 as part of create
1237
+ * Returns the required input amount for the provided exact output.
1238
+ */
1239
+ async simulateBundleExactOutput(createParams, params) {
1240
+ const bundler = this.getBundlerAddress();
1241
+ const { result } = await this.publicClient.simulateContract({
1242
+ address: bundler,
1243
+ abi: bundlerAbi,
1244
+ functionName: "simulateBundleExactOut",
1245
+ args: [
1246
+ { ...createParams },
1247
+ {
1248
+ tokenIn: params.tokenIn,
1249
+ tokenOut: params.tokenOut,
1250
+ amount: params.amount,
1251
+ fee: params.fee,
1252
+ sqrtPriceLimitX96: params.sqrtPriceLimitX96
1253
+ }
1254
+ ]
1255
+ });
1256
+ return result;
1257
+ }
1258
+ // Bundler helpers (Multicurve/V4)
1259
+ async simulateMulticurveBundleExactOut(createParams, params) {
1260
+ const bundler = this.getBundlerAddress();
1261
+ await this.ensureMulticurveBundlerSupport(bundler);
1262
+ const exactAmountOut = params?.exactAmountOut ?? 0n;
1263
+ this.ensureUint128(exactAmountOut, "exactAmountOut", { allowZero: true });
1264
+ const hookData = "0x";
1265
+ const { result } = await this.publicClient.simulateContract({
1266
+ address: bundler,
1267
+ abi: bundlerAbi,
1268
+ functionName: "simulateMulticurveBundleExactOut",
1269
+ args: [
1270
+ { ...createParams },
1271
+ exactAmountOut,
1272
+ hookData
1273
+ ]
1274
+ });
1275
+ const { asset, poolKey, amount, gasEstimate } = this.parseMulticurveBundleResult(result);
1276
+ return {
1277
+ asset,
1278
+ poolKey,
1279
+ amountIn: amount,
1280
+ gasEstimate
1281
+ };
1282
+ }
1283
+ async simulateMulticurveBundleExactIn(createParams, params) {
1284
+ const bundler = this.getBundlerAddress();
1285
+ await this.ensureMulticurveBundlerSupport(bundler);
1286
+ if (params.exactAmountIn === void 0) {
1287
+ throw new Error("exactAmountIn is required for multicurve bundle simulations");
1288
+ }
1289
+ const exactAmountIn = params.exactAmountIn;
1290
+ this.ensureUint128(exactAmountIn, "exactAmountIn");
1291
+ const hookData = "0x";
1292
+ const { result } = await this.publicClient.simulateContract({
1293
+ address: bundler,
1294
+ abi: bundlerAbi,
1295
+ functionName: "simulateMulticurveBundleExactIn",
1296
+ args: [
1297
+ { ...createParams },
1298
+ exactAmountIn,
1299
+ hookData
1300
+ ]
1301
+ });
1302
+ const { asset, poolKey, amount, gasEstimate } = this.parseMulticurveBundleResult(result);
1303
+ return {
1304
+ asset,
1305
+ poolKey,
1306
+ amountOut: amount,
1307
+ gasEstimate
1308
+ };
1309
+ }
1310
+ /**
1311
+ * Execute an atomic create + swap bundle through the Bundler
1312
+ * commands/inputs are Universal Router encoded values (e.g., from doppler-router)
1313
+ */
1314
+ async bundle(createParams, commands, inputs, options) {
1315
+ if (!this.walletClient) {
1316
+ throw new Error("Wallet client required for write operations");
1317
+ }
1318
+ const bundler = this.getBundlerAddress();
1319
+ const { request } = await this.publicClient.simulateContract({
1320
+ address: bundler,
1321
+ abi: bundlerAbi,
1322
+ functionName: "bundle",
1323
+ args: [
1324
+ { ...createParams },
1325
+ commands,
1326
+ inputs
1327
+ ],
1328
+ account: this.walletClient.account,
1329
+ value: options?.value ?? 0n
1330
+ });
1331
+ const gas = options?.gas ?? void 0;
1332
+ const tx = await this.walletClient.writeContract(gas ? { ...request, gas } : request);
1333
+ return tx;
1334
+ }
1335
+ ensureUint128(value, paramName, options = {}) {
1336
+ const { allowZero = false } = options;
1337
+ if (value < 0n) {
1338
+ throw new Error(`${paramName} cannot be negative`);
1339
+ }
1340
+ if (!allowZero && value === 0n) {
1341
+ throw new Error(`${paramName} must be greater than zero`);
1342
+ }
1343
+ if (value > MAX_UINT128) {
1344
+ throw new Error(`${paramName} exceeds uint128 range`);
1345
+ }
1346
+ }
1347
+ parseMulticurveBundleResult(result) {
1348
+ let asset;
1349
+ let poolKeyRaw;
1350
+ let amount;
1351
+ let gasEstimate;
1352
+ if (Array.isArray(result)) {
1353
+ if (result.length < 4) {
1354
+ throw new Error("Unexpected multicurve bundle simulation result shape");
1355
+ }
1356
+ asset = result[0];
1357
+ poolKeyRaw = result[1];
1358
+ amount = result[2];
1359
+ gasEstimate = result[3];
1360
+ } else if (result && typeof result === "object") {
1361
+ const obj = result;
1362
+ asset = obj.asset;
1363
+ poolKeyRaw = obj.poolKey;
1364
+ amount = obj.amountIn ?? obj.amountOut ?? obj.amount;
1365
+ gasEstimate = obj.gasEstimate;
1366
+ } else {
1367
+ throw new Error("Unexpected multicurve bundle simulation result format");
1368
+ }
1369
+ if (asset === void 0 || poolKeyRaw === void 0 || amount === void 0 || gasEstimate === void 0) {
1370
+ throw new Error("Incomplete multicurve bundle simulation result");
1371
+ }
1372
+ return {
1373
+ asset,
1374
+ poolKey: this.normalizePoolKey(poolKeyRaw),
1375
+ amount,
1376
+ gasEstimate
1377
+ };
1378
+ }
1379
+ normalizePoolKey(value) {
1380
+ if (Array.isArray(value)) {
1381
+ const [currency0, currency1, feeRaw, tickSpacingRaw, hooks] = value;
1382
+ const feeValue = Number(feeRaw);
1383
+ const tickSpacingValue = Number(tickSpacingRaw);
1384
+ if (!Number.isFinite(feeValue) || !Number.isFinite(tickSpacingValue)) {
1385
+ throw new Error("Invalid pool key numeric fields in multicurve bundle simulation result");
1386
+ }
1387
+ return {
1388
+ currency0,
1389
+ currency1,
1390
+ fee: feeValue,
1391
+ tickSpacing: tickSpacingValue,
1392
+ hooks
1393
+ };
1394
+ }
1395
+ if (value && typeof value === "object") {
1396
+ const { currency0, currency1, fee, tickSpacing, hooks } = value;
1397
+ const feeValue = Number(fee);
1398
+ const tickSpacingValue = Number(tickSpacing);
1399
+ if (!Number.isFinite(feeValue) || !Number.isFinite(tickSpacingValue)) {
1400
+ throw new Error("Invalid pool key numeric fields in multicurve bundle simulation result");
1401
+ }
1402
+ return {
1403
+ currency0,
1404
+ currency1,
1405
+ fee: feeValue,
1406
+ tickSpacing: tickSpacingValue,
1407
+ hooks
1408
+ };
1409
+ }
1410
+ throw new Error("Unable to normalize PoolKey from multicurve bundle simulation result");
1411
+ }
1412
+ /**
1413
+ * Mines a salt and hook address with the appropriate flags
1414
+ *
1415
+ * This method iterates through possible salt values to find a combination that:
1416
+ * - Produces a hook address with required Doppler flags
1417
+ * - Maintains proper token ordering relative to numeraire
1418
+ * - Ensures deterministic deployment addresses
1419
+ *
1420
+ * @param params - Parameters for hook address mining
1421
+ * @returns Tuple of [salt, hook address, token address, pool data, token data]
1422
+ * @throws {Error} If no valid salt can be found within the search limit
1423
+ * @private
1424
+ */
1425
+ mineHookAddress(params) {
1426
+ getAddresses(this.chainId);
1427
+ const isToken0 = isToken0Expected(params.numeraire);
1428
+ const {
1429
+ minimumProceeds,
1430
+ maximumProceeds,
1431
+ startingTime,
1432
+ endingTime,
1433
+ startingTick,
1434
+ endingTick,
1435
+ epochLength,
1436
+ gamma,
1437
+ numPDSlugs,
1438
+ fee,
1439
+ tickSpacing
1440
+ } = params.poolInitializerData;
1441
+ const poolInitializerData = encodeAbiParameters(
1442
+ [
1443
+ { type: "uint256" },
1444
+ { type: "uint256" },
1445
+ { type: "uint256" },
1446
+ { type: "uint256" },
1447
+ { type: "int24" },
1448
+ { type: "int24" },
1449
+ { type: "uint256" },
1450
+ { type: "int24" },
1451
+ { type: "bool" },
1452
+ { type: "uint256" },
1453
+ { type: "uint24" },
1454
+ { type: "int24" }
1455
+ ],
1456
+ [
1457
+ minimumProceeds,
1458
+ maximumProceeds,
1459
+ startingTime,
1460
+ endingTime,
1461
+ startingTick,
1462
+ endingTick,
1463
+ epochLength,
1464
+ gamma,
1465
+ isToken0,
1466
+ numPDSlugs,
1467
+ fee,
1468
+ tickSpacing
1469
+ ]
1470
+ );
1471
+ const isBase = this.chainId === CHAIN_IDS.BASE;
1472
+ const { poolManager, numTokensToSell, poolInitializer } = params;
1473
+ const hookInitHashData = encodeAbiParameters(
1474
+ [
1475
+ { type: "address" },
1476
+ { type: "uint256" },
1477
+ { type: "uint256" },
1478
+ { type: "uint256" },
1479
+ { type: "uint256" },
1480
+ { type: "uint256" },
1481
+ { type: "int24" },
1482
+ { type: "int24" },
1483
+ { type: "uint256" },
1484
+ { type: "int24" },
1485
+ { type: "bool" },
1486
+ { type: "uint256" },
1487
+ { type: "address" },
1488
+ { type: "uint24" }
1489
+ ],
1490
+ [
1491
+ poolManager,
1492
+ numTokensToSell,
1493
+ minimumProceeds,
1494
+ maximumProceeds,
1495
+ startingTime,
1496
+ endingTime,
1497
+ startingTick,
1498
+ endingTick,
1499
+ epochLength,
1500
+ gamma,
1501
+ isToken0,
1502
+ numPDSlugs,
1503
+ poolInitializer,
1504
+ fee
1505
+ ]
1506
+ );
1507
+ const hookInitHash = keccak256(
1508
+ encodePacked(
1509
+ ["bytes", "bytes"],
1510
+ [isBase ? DopplerBytecodeBaseMainnet : DopplerBytecode, hookInitHashData]
1511
+ )
1512
+ );
1513
+ const tokenFactoryData = params.tokenVariant === "doppler404" ? (() => {
1514
+ const t = params.tokenFactoryData;
1515
+ return encodeAbiParameters(
1516
+ [
1517
+ { type: "string" },
1518
+ { type: "string" },
1519
+ { type: "string" },
1520
+ { type: "uint256" }
1521
+ ],
1522
+ [t.name, t.symbol, t.baseURI, t.unit ?? 1000n]
1523
+ );
1524
+ })() : (() => {
1525
+ const {
1526
+ name,
1527
+ symbol,
1528
+ yearlyMintRate,
1529
+ vestingDuration,
1530
+ recipients,
1531
+ amounts,
1532
+ tokenURI
1533
+ } = params.tokenFactoryData;
1534
+ return encodeAbiParameters(
1535
+ [
1536
+ { type: "string" },
1537
+ { type: "string" },
1538
+ { type: "uint256" },
1539
+ { type: "uint256" },
1540
+ { type: "address[]" },
1541
+ { type: "uint256[]" },
1542
+ { type: "string" }
1543
+ ],
1544
+ [
1545
+ name,
1546
+ symbol,
1547
+ yearlyMintRate,
1548
+ vestingDuration,
1549
+ recipients,
1550
+ amounts,
1551
+ tokenURI
1552
+ ]
1553
+ );
1554
+ })();
1555
+ const { airlock, initialSupply } = params;
1556
+ let tokenInitHash;
1557
+ if (params.tokenVariant === "doppler404") {
1558
+ const { name, symbol, baseURI } = params.tokenFactoryData;
1559
+ const { airlock: airlock2, initialSupply: initialSupply2 } = params;
1560
+ const initHashData = encodeAbiParameters(
1561
+ [
1562
+ { type: "string" },
1563
+ { type: "string" },
1564
+ { type: "uint256" },
1565
+ { type: "address" },
1566
+ { type: "address" },
1567
+ { type: "string" }
1568
+ ],
1569
+ [
1570
+ name,
1571
+ symbol,
1572
+ initialSupply2,
1573
+ airlock2,
1574
+ airlock2,
1575
+ baseURI
1576
+ ]
1577
+ );
1578
+ tokenInitHash = keccak256(
1579
+ encodePacked(["bytes", "bytes"], [DopplerDN404Bytecode, initHashData])
1580
+ );
1581
+ } else {
1582
+ const { name, symbol, yearlyMintRate, vestingDuration, recipients, amounts, tokenURI } = params.tokenFactoryData;
1583
+ const { airlock: airlock2, initialSupply: initialSupply2 } = params;
1584
+ const initHashData = encodeAbiParameters(
1585
+ [
1586
+ { type: "string" },
1587
+ { type: "string" },
1588
+ { type: "uint256" },
1589
+ { type: "address" },
1590
+ { type: "address" },
1591
+ { type: "uint256" },
1592
+ { type: "uint256" },
1593
+ { type: "address[]" },
1594
+ { type: "uint256[]" },
1595
+ { type: "string" }
1596
+ ],
1597
+ [
1598
+ name,
1599
+ symbol,
1600
+ initialSupply2,
1601
+ airlock2,
1602
+ airlock2,
1603
+ yearlyMintRate,
1604
+ vestingDuration,
1605
+ recipients,
1606
+ amounts,
1607
+ tokenURI
1608
+ ]
1609
+ );
1610
+ tokenInitHash = keccak256(
1611
+ encodePacked(["bytes", "bytes"], [params.customDerc20Bytecode ?? DERC20Bytecode, initHashData])
1612
+ );
1613
+ }
1614
+ const flags = BigInt(
1615
+ 1 << 13 | // BEFORE_INITIALIZE_FLAG
1616
+ 1 << 12 | // AFTER_INITIALIZE_FLAG
1617
+ 1 << 11 | // BEFORE_ADD_LIQUIDITY_FLAG
1618
+ 1 << 7 | // BEFORE_SWAP_FLAG
1619
+ 1 << 6 | // AFTER_SWAP_FLAG
1620
+ 1 << 5
1621
+ // BEFORE_DONATE_FLAG
1622
+ );
1623
+ for (let salt = BigInt(0); salt < BigInt(1e6); salt++) {
1624
+ const saltBytes = `0x${salt.toString(16).padStart(64, "0")}`;
1625
+ const hook = this.computeCreate2Address(
1626
+ saltBytes,
1627
+ hookInitHash,
1628
+ params.deployer
1629
+ );
1630
+ const hookBigInt = BigInt(hook);
1631
+ if (tokenInitHash) {
1632
+ const token = this.computeCreate2Address(
1633
+ saltBytes,
1634
+ tokenInitHash,
1635
+ params.tokenFactory
1636
+ );
1637
+ const tokenBigInt = BigInt(token);
1638
+ const numeraireBigInt = BigInt(params.numeraire);
1639
+ if ((hookBigInt & FLAG_MASK) === flags && (isToken0 && tokenBigInt < numeraireBigInt || !isToken0 && tokenBigInt > numeraireBigInt)) {
1640
+ return [saltBytes, hook, token, poolInitializerData, tokenFactoryData];
1641
+ }
1642
+ }
1643
+ }
1644
+ throw new Error("AirlockMiner: could not find salt");
1645
+ }
1646
+ /**
1647
+ * Computes the CREATE2 address for a contract deployment
1648
+ * @param salt - The salt used for deployment
1649
+ * @param initCodeHash - Hash of the initialization code
1650
+ * @param deployer - Address of the deploying contract
1651
+ * @returns The computed contract address
1652
+ * @private
1653
+ */
1654
+ computeCreate2Address(salt, initCodeHash, deployer) {
1655
+ const encoded = encodePacked(
1656
+ ["bytes1", "address", "bytes32", "bytes32"],
1657
+ ["0xff", deployer, salt, initCodeHash]
1658
+ );
1659
+ return getAddress(`0x${keccak256(encoded).slice(-40)}`);
1660
+ }
1661
+ /**
1662
+ * Compute V4 pool ID from pool key components
1663
+ */
1664
+ computePoolId(poolKey) {
1665
+ const encoded = encodeAbiParameters(
1666
+ [
1667
+ { type: "address" },
1668
+ { type: "address" },
1669
+ { type: "uint24" },
1670
+ { type: "int24" },
1671
+ { type: "address" }
1672
+ ],
1673
+ [
1674
+ poolKey.currency0,
1675
+ poolKey.currency1,
1676
+ poolKey.fee,
1677
+ poolKey.tickSpacing,
1678
+ poolKey.hooks
1679
+ ]
1680
+ );
1681
+ return keccak256(encoded);
1682
+ }
1683
+ async ensureMulticurveBundlerSupport(bundler) {
1684
+ if (this.multicurveBundlerSupport.get(bundler)) {
1685
+ return;
1686
+ }
1687
+ const client = this.publicClient;
1688
+ if (!client || typeof client.getBytecode !== "function") {
1689
+ this.multicurveBundlerSupport.set(bundler, true);
1690
+ return;
1691
+ }
1692
+ const bytecode = await client.getBytecode({ address: bundler });
1693
+ const supports = Boolean(bytecode && MULTICURVE_BUNDLER_SELECTORS.every((selector) => bytecode.includes(selector.slice(2))));
1694
+ if (!supports) {
1695
+ throw new Error(
1696
+ `Bundler at ${bundler} does not support multicurve bundling. Ensure the Doppler Bundler has been upgraded and update chain addresses.`
1697
+ );
1698
+ }
1699
+ this.multicurveBundlerSupport.set(bundler, true);
1700
+ }
1701
+ };
1702
+ var MULTICURVE_BUNDLER_SELECTORS = ["0xe2e9faa1", "0x07087b06"];
1703
+
1704
+ export { DopplerFactory };
1705
+ //# sourceMappingURL=chunk-TKSHYEYA.mjs.map
1706
+ //# sourceMappingURL=chunk-TKSHYEYA.mjs.map