@clober/v2-sdk 0.0.11 → 0.0.12-8.dev.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 (347) hide show
  1. package/README.md +12 -4
  2. package/dist/cjs/abis/core/book-manager-abi.js +112 -0
  3. package/dist/cjs/abis/core/book-manager-abi.js.map +1 -0
  4. package/dist/cjs/abis/core/book-viewer-abi.js +137 -5
  5. package/dist/cjs/abis/core/book-viewer-abi.js.map +1 -1
  6. package/dist/cjs/abis/core/controller-abi.js +1 -6
  7. package/dist/cjs/abis/core/controller-abi.js.map +1 -1
  8. package/dist/cjs/abis/rebalancer/minter-abi.js +262 -0
  9. package/dist/cjs/abis/rebalancer/minter-abi.js.map +1 -0
  10. package/dist/cjs/abis/rebalancer/mock-swap-abi.js +95 -0
  11. package/dist/cjs/abis/rebalancer/mock-swap-abi.js.map +1 -0
  12. package/dist/cjs/abis/rebalancer/operator-abi.js +401 -0
  13. package/dist/cjs/abis/rebalancer/operator-abi.js.map +1 -0
  14. package/dist/cjs/abis/rebalancer/rebalancer-abi.js +1326 -0
  15. package/dist/cjs/abis/rebalancer/rebalancer-abi.js.map +1 -0
  16. package/dist/cjs/abis/rebalancer/strategy-abi.js +895 -0
  17. package/dist/cjs/abis/rebalancer/strategy-abi.js.map +1 -0
  18. package/dist/cjs/apis/chart-logs.js +30 -13
  19. package/dist/cjs/apis/chart-logs.js.map +1 -1
  20. package/dist/cjs/apis/market.js +45 -22
  21. package/dist/cjs/apis/market.js.map +1 -1
  22. package/dist/cjs/apis/odos.js +100 -0
  23. package/dist/cjs/apis/odos.js.map +1 -0
  24. package/dist/cjs/apis/open-order.js +75 -44
  25. package/dist/cjs/apis/open-order.js.map +1 -1
  26. package/dist/cjs/apis/pool.js +95 -0
  27. package/dist/cjs/apis/pool.js.map +1 -0
  28. package/dist/cjs/apis/strategy.js +53 -0
  29. package/dist/cjs/apis/strategy.js.map +1 -0
  30. package/dist/cjs/approval.js +83 -26
  31. package/dist/cjs/approval.js.map +1 -1
  32. package/dist/cjs/call.js +739 -107
  33. package/dist/cjs/call.js.map +1 -1
  34. package/dist/cjs/constants/addresses.js +68 -1
  35. package/dist/cjs/constants/addresses.js.map +1 -1
  36. package/dist/cjs/constants/chain.js +23 -2
  37. package/dist/cjs/constants/chain.js.map +1 -1
  38. package/dist/cjs/constants/currency.js +86 -3
  39. package/dist/cjs/constants/currency.js.map +1 -1
  40. package/dist/cjs/constants/fee.js +21 -2
  41. package/dist/cjs/constants/fee.js.map +1 -1
  42. package/dist/cjs/constants/permit.js +14 -0
  43. package/dist/cjs/constants/permit.js.map +1 -0
  44. package/dist/cjs/constants/price.js +2 -1
  45. package/dist/cjs/constants/price.js.map +1 -1
  46. package/dist/cjs/constants/rise-sepolia.js +29 -0
  47. package/dist/cjs/constants/rise-sepolia.js.map +1 -0
  48. package/dist/cjs/constants/subgraph.js +37 -0
  49. package/dist/cjs/constants/subgraph.js.map +1 -0
  50. package/dist/cjs/constants/test-chain.js +50 -0
  51. package/dist/cjs/constants/test-chain.js.map +1 -0
  52. package/dist/cjs/constants/tick.js +6 -0
  53. package/dist/cjs/constants/tick.js.map +1 -0
  54. package/dist/cjs/index.js +1 -1
  55. package/dist/cjs/index.js.map +1 -1
  56. package/dist/cjs/model/book.js +62 -35
  57. package/dist/cjs/model/book.js.map +1 -1
  58. package/dist/cjs/model/market.js +61 -26
  59. package/dist/cjs/model/market.js.map +1 -1
  60. package/dist/cjs/model/pool.js +239 -0
  61. package/dist/cjs/model/pool.js.map +1 -0
  62. package/dist/cjs/type.js.map +1 -1
  63. package/dist/cjs/utils/allowance.js +39 -0
  64. package/dist/cjs/utils/allowance.js.map +1 -0
  65. package/dist/cjs/utils/approval.js +2 -3
  66. package/dist/cjs/utils/approval.js.map +1 -1
  67. package/dist/cjs/utils/bigint.js +5 -1
  68. package/dist/cjs/utils/bigint.js.map +1 -1
  69. package/dist/cjs/utils/book-id.js +7 -7
  70. package/dist/cjs/utils/book-id.js.map +1 -1
  71. package/dist/cjs/utils/build-transaction.js +3 -4
  72. package/dist/cjs/utils/build-transaction.js.map +1 -1
  73. package/dist/cjs/utils/currency.js +61 -27
  74. package/dist/cjs/utils/currency.js.map +1 -1
  75. package/dist/cjs/utils/market.js +1 -1
  76. package/dist/cjs/utils/market.js.map +1 -1
  77. package/dist/cjs/utils/math.js +3 -1
  78. package/dist/cjs/utils/math.js.map +1 -1
  79. package/dist/cjs/utils/open.js +35 -25
  80. package/dist/cjs/utils/open.js.map +1 -1
  81. package/dist/cjs/utils/order.js +50 -126
  82. package/dist/cjs/utils/order.js.map +1 -1
  83. package/dist/cjs/utils/pool-key.js +17 -0
  84. package/dist/cjs/utils/pool-key.js.map +1 -0
  85. package/dist/cjs/utils/pool.js +88 -0
  86. package/dist/cjs/utils/pool.js.map +1 -0
  87. package/dist/cjs/utils/prices.js +40 -5
  88. package/dist/cjs/utils/prices.js.map +1 -1
  89. package/dist/cjs/utils/quotes.js +16 -0
  90. package/dist/cjs/utils/quotes.js.map +1 -0
  91. package/dist/cjs/utils/tick.js +12 -1
  92. package/dist/cjs/utils/tick.js.map +1 -1
  93. package/dist/cjs/utils/time-series.js +31 -0
  94. package/dist/cjs/utils/time-series.js.map +1 -0
  95. package/dist/cjs/utils/unit-size.js +14 -0
  96. package/dist/cjs/utils/unit-size.js.map +1 -0
  97. package/dist/cjs/utils.js +18 -0
  98. package/dist/cjs/utils.js.map +1 -0
  99. package/dist/cjs/view.js +308 -44
  100. package/dist/cjs/view.js.map +1 -1
  101. package/dist/esm/abis/core/book-manager-abi.js +109 -0
  102. package/dist/esm/abis/core/book-manager-abi.js.map +1 -0
  103. package/dist/esm/abis/core/book-viewer-abi.js +137 -5
  104. package/dist/esm/abis/core/book-viewer-abi.js.map +1 -1
  105. package/dist/esm/abis/core/controller-abi.js +1 -6
  106. package/dist/esm/abis/core/controller-abi.js.map +1 -1
  107. package/dist/esm/abis/rebalancer/minter-abi.js +259 -0
  108. package/dist/esm/abis/rebalancer/minter-abi.js.map +1 -0
  109. package/dist/esm/abis/rebalancer/mock-swap-abi.js +92 -0
  110. package/dist/esm/abis/rebalancer/mock-swap-abi.js.map +1 -0
  111. package/dist/esm/abis/rebalancer/operator-abi.js +398 -0
  112. package/dist/esm/abis/rebalancer/operator-abi.js.map +1 -0
  113. package/dist/esm/abis/rebalancer/rebalancer-abi.js +1323 -0
  114. package/dist/esm/abis/rebalancer/rebalancer-abi.js.map +1 -0
  115. package/dist/esm/abis/rebalancer/strategy-abi.js +892 -0
  116. package/dist/esm/abis/rebalancer/strategy-abi.js.map +1 -0
  117. package/dist/esm/apis/chart-logs.js +29 -12
  118. package/dist/esm/apis/chart-logs.js.map +1 -1
  119. package/dist/esm/apis/market.js +47 -24
  120. package/dist/esm/apis/market.js.map +1 -1
  121. package/dist/esm/apis/odos.js +94 -0
  122. package/dist/esm/apis/odos.js.map +1 -0
  123. package/dist/esm/apis/open-order.js +78 -44
  124. package/dist/esm/apis/open-order.js.map +1 -1
  125. package/dist/esm/apis/pool.js +96 -0
  126. package/dist/esm/apis/pool.js.map +1 -0
  127. package/dist/esm/apis/strategy.js +48 -0
  128. package/dist/esm/apis/strategy.js.map +1 -0
  129. package/dist/esm/approval.js +107 -25
  130. package/dist/esm/approval.js.map +1 -1
  131. package/dist/esm/call.js +772 -145
  132. package/dist/esm/call.js.map +1 -1
  133. package/dist/esm/constants/addresses.js +69 -2
  134. package/dist/esm/constants/addresses.js.map +1 -1
  135. package/dist/esm/constants/chain.js +23 -2
  136. package/dist/esm/constants/chain.js.map +1 -1
  137. package/dist/esm/constants/currency.js +87 -2
  138. package/dist/esm/constants/currency.js.map +1 -1
  139. package/dist/esm/constants/fee.js +21 -2
  140. package/dist/esm/constants/fee.js.map +1 -1
  141. package/dist/esm/constants/permit.js +11 -0
  142. package/dist/esm/constants/permit.js.map +1 -0
  143. package/dist/esm/constants/price.js +1 -0
  144. package/dist/esm/constants/price.js.map +1 -1
  145. package/dist/esm/constants/rise-sepolia.js +26 -0
  146. package/dist/esm/constants/rise-sepolia.js.map +1 -0
  147. package/dist/esm/constants/subgraph.js +33 -0
  148. package/dist/esm/constants/subgraph.js.map +1 -0
  149. package/dist/esm/constants/test-chain.js +47 -0
  150. package/dist/esm/constants/test-chain.js.map +1 -0
  151. package/dist/esm/constants/tick.js +3 -0
  152. package/dist/esm/constants/tick.js.map +1 -0
  153. package/dist/esm/index.js +1 -1
  154. package/dist/esm/index.js.map +1 -1
  155. package/dist/esm/model/book.js +62 -35
  156. package/dist/esm/model/book.js.map +1 -1
  157. package/dist/esm/model/market.js +63 -28
  158. package/dist/esm/model/market.js.map +1 -1
  159. package/dist/esm/model/pool.js +236 -0
  160. package/dist/esm/model/pool.js.map +1 -0
  161. package/dist/esm/type.js.map +1 -1
  162. package/dist/esm/utils/allowance.js +35 -0
  163. package/dist/esm/utils/allowance.js.map +1 -0
  164. package/dist/esm/utils/approval.js +2 -3
  165. package/dist/esm/utils/approval.js.map +1 -1
  166. package/dist/esm/utils/bigint.js +2 -0
  167. package/dist/esm/utils/bigint.js.map +1 -1
  168. package/dist/esm/utils/book-id.js +7 -7
  169. package/dist/esm/utils/book-id.js.map +1 -1
  170. package/dist/esm/utils/build-transaction.js +3 -4
  171. package/dist/esm/utils/build-transaction.js.map +1 -1
  172. package/dist/esm/utils/currency.js +59 -25
  173. package/dist/esm/utils/currency.js.map +1 -1
  174. package/dist/esm/utils/market.js +1 -1
  175. package/dist/esm/utils/market.js.map +1 -1
  176. package/dist/esm/utils/math.js +1 -0
  177. package/dist/esm/utils/math.js.map +1 -1
  178. package/dist/esm/utils/open.js +33 -23
  179. package/dist/esm/utils/open.js.map +1 -1
  180. package/dist/esm/utils/order.js +49 -125
  181. package/dist/esm/utils/order.js.map +1 -1
  182. package/dist/esm/utils/pool-key.js +12 -0
  183. package/dist/esm/utils/pool-key.js.map +1 -0
  184. package/dist/esm/utils/pool.js +84 -0
  185. package/dist/esm/utils/pool.js.map +1 -0
  186. package/dist/esm/utils/prices.js +39 -5
  187. package/dist/esm/utils/prices.js.map +1 -1
  188. package/dist/esm/utils/quotes.js +12 -0
  189. package/dist/esm/utils/quotes.js.map +1 -0
  190. package/dist/esm/utils/tick.js +11 -1
  191. package/dist/esm/utils/tick.js.map +1 -1
  192. package/dist/esm/utils/time-series.js +27 -0
  193. package/dist/esm/utils/time-series.js.map +1 -0
  194. package/dist/esm/utils/unit-size.js +10 -0
  195. package/dist/esm/utils/unit-size.js.map +1 -0
  196. package/dist/esm/utils.js +5 -0
  197. package/dist/esm/utils.js.map +1 -0
  198. package/dist/esm/view.js +379 -61
  199. package/dist/esm/view.js.map +1 -1
  200. package/dist/tsconfig.build.tsbuildinfo +1 -1
  201. package/dist/types/abis/core/book-manager-abi.d.ts +82 -0
  202. package/dist/types/abis/core/book-manager-abi.d.ts.map +1 -0
  203. package/dist/types/abis/core/book-viewer-abi.d.ts +107 -5
  204. package/dist/types/abis/core/book-viewer-abi.d.ts.map +1 -1
  205. package/dist/types/abis/core/controller-abi.d.ts +1 -5
  206. package/dist/types/abis/core/controller-abi.d.ts.map +1 -1
  207. package/dist/types/abis/rebalancer/minter-abi.d.ts +198 -0
  208. package/dist/types/abis/rebalancer/minter-abi.d.ts.map +1 -0
  209. package/dist/types/abis/rebalancer/mock-swap-abi.d.ts +70 -0
  210. package/dist/types/abis/rebalancer/mock-swap-abi.d.ts.map +1 -0
  211. package/dist/types/abis/rebalancer/operator-abi.d.ts +308 -0
  212. package/dist/types/abis/rebalancer/operator-abi.d.ts.map +1 -0
  213. package/dist/types/abis/rebalancer/rebalancer-abi.d.ts +1023 -0
  214. package/dist/types/abis/rebalancer/rebalancer-abi.d.ts.map +1 -0
  215. package/dist/types/abis/rebalancer/strategy-abi.d.ts +690 -0
  216. package/dist/types/abis/rebalancer/strategy-abi.d.ts.map +1 -0
  217. package/dist/types/apis/chart-logs.d.ts +3 -0
  218. package/dist/types/apis/chart-logs.d.ts.map +1 -1
  219. package/dist/types/apis/market.d.ts +2 -1
  220. package/dist/types/apis/market.d.ts.map +1 -1
  221. package/dist/types/apis/odos.d.ts +28 -0
  222. package/dist/types/apis/odos.d.ts.map +1 -0
  223. package/dist/types/apis/open-order.d.ts +3 -2
  224. package/dist/types/apis/open-order.d.ts.map +1 -1
  225. package/dist/types/apis/pool.d.ts +11 -0
  226. package/dist/types/apis/pool.d.ts.map +1 -0
  227. package/dist/types/apis/strategy.d.ts +6 -0
  228. package/dist/types/apis/strategy.d.ts.map +1 -0
  229. package/dist/types/approval.d.ts +37 -3
  230. package/dist/types/approval.d.ts.map +1 -1
  231. package/dist/types/call.d.ts +233 -54
  232. package/dist/types/call.d.ts.map +1 -1
  233. package/dist/types/constants/addresses.d.ts +4 -0
  234. package/dist/types/constants/addresses.d.ts.map +1 -1
  235. package/dist/types/constants/chain.d.ts +9 -2
  236. package/dist/types/constants/chain.d.ts.map +1 -1
  237. package/dist/types/constants/currency.d.ts +8 -0
  238. package/dist/types/constants/currency.d.ts.map +1 -1
  239. package/dist/types/constants/fee.d.ts +7 -2
  240. package/dist/types/constants/fee.d.ts.map +1 -1
  241. package/dist/types/constants/permit.d.ts +10 -0
  242. package/dist/types/constants/permit.d.ts.map +1 -0
  243. package/dist/types/constants/price.d.ts +1 -0
  244. package/dist/types/constants/price.d.ts.map +1 -1
  245. package/dist/types/constants/rise-sepolia.d.ts +32 -0
  246. package/dist/types/constants/rise-sepolia.d.ts.map +1 -0
  247. package/dist/types/constants/subgraph.d.ts +8 -0
  248. package/dist/types/constants/subgraph.d.ts.map +1 -0
  249. package/dist/types/constants/test-chain.d.ts +4 -0
  250. package/dist/types/constants/test-chain.d.ts.map +1 -0
  251. package/dist/types/constants/tick.d.ts +3 -0
  252. package/dist/types/constants/tick.d.ts.map +1 -0
  253. package/dist/types/index.d.ts +1 -1
  254. package/dist/types/index.d.ts.map +1 -1
  255. package/dist/types/model/book.d.ts +25 -33
  256. package/dist/types/model/book.d.ts.map +1 -1
  257. package/dist/types/model/currency.d.ts +7 -0
  258. package/dist/types/model/currency.d.ts.map +1 -1
  259. package/dist/types/model/depth.d.ts +4 -3
  260. package/dist/types/model/depth.d.ts.map +1 -1
  261. package/dist/types/model/market.d.ts +24 -13
  262. package/dist/types/model/market.d.ts.map +1 -1
  263. package/dist/types/model/open-order.d.ts +20 -27
  264. package/dist/types/model/open-order.d.ts.map +1 -1
  265. package/dist/types/model/pool.d.ts +76 -0
  266. package/dist/types/model/pool.d.ts.map +1 -0
  267. package/dist/types/type.d.ts +95 -6
  268. package/dist/types/type.d.ts.map +1 -1
  269. package/dist/types/utils/allowance.d.ts +3 -0
  270. package/dist/types/utils/allowance.d.ts.map +1 -0
  271. package/dist/types/utils/approval.d.ts +2 -1
  272. package/dist/types/utils/approval.d.ts.map +1 -1
  273. package/dist/types/utils/bigint.d.ts +2 -0
  274. package/dist/types/utils/bigint.d.ts.map +1 -1
  275. package/dist/types/utils/book-id.d.ts +2 -1
  276. package/dist/types/utils/book-id.d.ts.map +1 -1
  277. package/dist/types/utils/build-transaction.d.ts +3 -3
  278. package/dist/types/utils/build-transaction.d.ts.map +1 -1
  279. package/dist/types/utils/currency.d.ts +3 -2
  280. package/dist/types/utils/currency.d.ts.map +1 -1
  281. package/dist/types/utils/math.d.ts +1 -0
  282. package/dist/types/utils/math.d.ts.map +1 -1
  283. package/dist/types/utils/open.d.ts +2 -1
  284. package/dist/types/utils/open.d.ts.map +1 -1
  285. package/dist/types/utils/order.d.ts +4 -11
  286. package/dist/types/utils/order.d.ts.map +1 -1
  287. package/dist/types/utils/pool-key.d.ts +3 -0
  288. package/dist/types/utils/pool-key.d.ts.map +1 -0
  289. package/dist/types/utils/pool.d.ts +11 -0
  290. package/dist/types/utils/pool.d.ts.map +1 -0
  291. package/dist/types/utils/prices.d.ts +13 -2
  292. package/dist/types/utils/prices.d.ts.map +1 -1
  293. package/dist/types/utils/quotes.d.ts +2 -0
  294. package/dist/types/utils/quotes.d.ts.map +1 -0
  295. package/dist/types/utils/tick.d.ts +1 -0
  296. package/dist/types/utils/tick.d.ts.map +1 -1
  297. package/dist/types/utils/time-series.d.ts +4 -0
  298. package/dist/types/utils/time-series.d.ts.map +1 -0
  299. package/dist/types/utils/unit-size.d.ts +4 -0
  300. package/dist/types/utils/unit-size.d.ts.map +1 -0
  301. package/dist/types/utils.d.ts +5 -0
  302. package/dist/types/utils.d.ts.map +1 -0
  303. package/dist/types/view.d.ts +236 -30
  304. package/dist/types/view.d.ts.map +1 -1
  305. package/package.json +4 -3
  306. package/dist/cjs/abis/core/params-abi.js +0 -62
  307. package/dist/cjs/abis/core/params-abi.js.map +0 -1
  308. package/dist/cjs/apis/subgraph.js +0 -26
  309. package/dist/cjs/apis/subgraph.js.map +0 -1
  310. package/dist/cjs/constants/client.js +0 -14
  311. package/dist/cjs/constants/client.js.map +0 -1
  312. package/dist/cjs/constants/subgraph-url.js +0 -8
  313. package/dist/cjs/constants/subgraph-url.js.map +0 -1
  314. package/dist/cjs/signature.js +0 -145
  315. package/dist/cjs/signature.js.map +0 -1
  316. package/dist/cjs/utils/decorator.js +0 -13
  317. package/dist/cjs/utils/decorator.js.map +0 -1
  318. package/dist/cjs/utils/unit.js +0 -34
  319. package/dist/cjs/utils/unit.js.map +0 -1
  320. package/dist/esm/abis/core/params-abi.js +0 -59
  321. package/dist/esm/abis/core/params-abi.js.map +0 -1
  322. package/dist/esm/apis/subgraph.js +0 -22
  323. package/dist/esm/apis/subgraph.js.map +0 -1
  324. package/dist/esm/constants/client.js +0 -10
  325. package/dist/esm/constants/client.js.map +0 -1
  326. package/dist/esm/constants/subgraph-url.js +0 -5
  327. package/dist/esm/constants/subgraph-url.js.map +0 -1
  328. package/dist/esm/signature.js +0 -169
  329. package/dist/esm/signature.js.map +0 -1
  330. package/dist/esm/utils/decorator.js +0 -9
  331. package/dist/esm/utils/decorator.js.map +0 -1
  332. package/dist/esm/utils/unit.js +0 -30
  333. package/dist/esm/utils/unit.js.map +0 -1
  334. package/dist/types/abis/core/params-abi.d.ts +0 -21
  335. package/dist/types/abis/core/params-abi.d.ts.map +0 -1
  336. package/dist/types/apis/subgraph.d.ts +0 -3
  337. package/dist/types/apis/subgraph.d.ts.map +0 -1
  338. package/dist/types/constants/client.d.ts +0 -5
  339. package/dist/types/constants/client.d.ts.map +0 -1
  340. package/dist/types/constants/subgraph-url.d.ts +0 -5
  341. package/dist/types/constants/subgraph-url.d.ts.map +0 -1
  342. package/dist/types/signature.d.ts +0 -38
  343. package/dist/types/signature.d.ts.map +0 -1
  344. package/dist/types/utils/decorator.d.ts +0 -6
  345. package/dist/types/utils/decorator.d.ts.map +0 -1
  346. package/dist/types/utils/unit.d.ts +0 -4
  347. package/dist/types/utils/unit.d.ts.map +0 -1
package/dist/esm/call.js CHANGED
@@ -1,46 +1,64 @@
1
- import { formatUnits, isAddressEqual, parseUnits, zeroAddress, zeroHash, } from 'viem';
1
+ import { createPublicClient, formatUnits, getAddress, http, isAddressEqual, parseUnits, zeroAddress, zeroHash, } from 'viem';
2
2
  import { CHAIN_MAP } from './constants/chain';
3
- import { calculateUnit } from './utils/unit';
3
+ import { calculateUnitSize } from './utils/unit-size';
4
4
  import { CONTROLLER_ABI } from './abis/core/controller-abi';
5
5
  import { getDeadlineTimestampInSeconds } from './utils/time';
6
6
  import { buildTransaction } from './utils/build-transaction';
7
7
  import { CONTRACT_ADDRESSES } from './constants/addresses';
8
8
  import { MAKER_DEFAULT_POLICY, TAKER_DEFAULT_POLICY } from './constants/fee';
9
9
  import { fetchMarket } from './apis/market';
10
- import { parsePrice } from './utils/prices';
11
- import { fromPrice, invertPrice } from './utils/tick';
12
- import { getExpectedInput, getExpectedOutput } from './view';
10
+ import { convertHumanReadablePriceToRawPrice, formatPrice, parsePrice, } from './utils/prices';
11
+ import { invertTick, toPrice } from './utils/tick';
12
+ import { getExpectedInput, getExpectedOutput, getQuoteToken } from './view';
13
13
  import { toBookId } from './utils/book-id';
14
14
  import { fetchIsApprovedForAll } from './utils/approval';
15
- import { decorator } from './utils/decorator';
16
- import { fetchOrders } from './utils/order';
17
- import { quoteToBase } from './utils/decimals';
15
+ import { fetchOnChainOrders } from './utils/order';
18
16
  import { applyPercent } from './utils/bigint';
17
+ import { fetchPool } from './apis/pool';
18
+ import { REBALANCER_ABI } from './abis/rebalancer/rebalancer-abi';
19
+ import { getExpectedMintResult, getIdealDelta } from './utils/pool';
20
+ import { fetchCallData, fetchQuote } from './apis/odos';
21
+ import { MINTER_ABI } from './abis/rebalancer/minter-abi';
22
+ import { emptyERC20PermitParams } from './constants/permit';
23
+ import { abs } from './utils/math';
24
+ import { toBytes32 } from './utils/pool-key';
25
+ import { OPERATOR_ABI } from './abis/rebalancer/operator-abi';
26
+ import { STRATEGY_ABI } from './abis/rebalancer/strategy-abi';
27
+ import { fetchOpenOrdersByOrderIdsFromSubgraph } from './apis/open-order';
28
+ import { quotes } from './utils/quotes';
19
29
  /**
20
30
  * Build a transaction to open a market.
21
31
  *
22
32
  * @param chainId The chain ID of the blockchain.
33
+ * @param userAddress The address of the user.
23
34
  * @param inputToken The address of the input token.
24
35
  * @param outputToken The address of the output token.
25
- * @param options
26
- * @param options.rpcUrl The RPC URL of the blockchain.
36
+ * @param options {@link DefaultWriteContractOptions} options.
27
37
  * @returns A Promise resolving to a transaction object. If the market is already open, returns undefined.
28
38
  * @example
29
39
  * import { openMarket } from '@clober/v2-sdk'
30
40
  *
31
41
  * const transaction = await openMarket({
32
42
  * chainId: 421614,
43
+ * userAddress: '0xF8c1869Ecd4df136693C45EcE1b67f85B6bDaE69',
33
44
  * inputToken: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
34
45
  * outputToken: '0x0000000000000000000000000000000000000000'
35
46
  * })
36
47
  */
37
- export const openMarket = decorator(async ({ chainId, inputToken, outputToken, options, }) => {
38
- const market = await fetchMarket(chainId, [inputToken, outputToken]);
48
+ export const openMarket = async ({ chainId, userAddress, inputToken, outputToken, options, }) => {
49
+ const publicClient = createPublicClient({
50
+ chain: CHAIN_MAP[chainId],
51
+ transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
52
+ });
53
+ const market = await fetchMarket(publicClient, chainId, [inputToken, outputToken], !!(options && options.useSubgraph));
39
54
  const isBid = isAddressEqual(market.quote.address, inputToken);
40
- if ((isBid && !market.bidBookOpen) || (!isBid && !market.askBookOpen)) {
41
- const unit = await calculateUnit(chainId, isBid ? market.quote : market.base);
42
- return buildTransaction(chainId, {
55
+ if ((isBid && !market.bidBook.isOpened) ||
56
+ (!isBid && !market.askBook.isOpened)) {
57
+ const unitSize = calculateUnitSize(chainId, isBid ? market.quote : market.base);
58
+ return buildTransaction(publicClient, {
59
+ chain: CHAIN_MAP[chainId],
43
60
  address: CONTRACT_ADDRESSES[chainId].Controller,
61
+ account: userAddress,
44
62
  abi: CONTROLLER_ABI,
45
63
  functionName: 'open',
46
64
  args: [
@@ -48,11 +66,11 @@ export const openMarket = decorator(async ({ chainId, inputToken, outputToken, o
48
66
  {
49
67
  key: {
50
68
  base: outputToken,
51
- unit,
69
+ unitSize,
52
70
  quote: inputToken,
53
- makerPolicy: MAKER_DEFAULT_POLICY.value,
71
+ makerPolicy: MAKER_DEFAULT_POLICY[chainId].value,
54
72
  hooks: zeroAddress,
55
- takerPolicy: TAKER_DEFAULT_POLICY.value,
73
+ takerPolicy: TAKER_DEFAULT_POLICY[chainId].value,
56
74
  },
57
75
  hookData: zeroHash,
58
76
  },
@@ -62,7 +80,7 @@ export const openMarket = decorator(async ({ chainId, inputToken, outputToken, o
62
80
  }, options?.gasLimit);
63
81
  }
64
82
  return undefined;
65
- });
83
+ };
66
84
  /**
67
85
  * Places a limit order on the specified chain for trading tokens.
68
86
  *
@@ -72,23 +90,21 @@ export const openMarket = decorator(async ({ chainId, inputToken, outputToken, o
72
90
  * @param {`0x${string}`} outputToken The address of the token to be received as output.
73
91
  * @param {string} amount The amount of input tokens for the order.
74
92
  * @param {string} price The price at which the order should be executed.
75
- * @param {Object} [options] Optional parameters for the limit order.
93
+ * @param options {@link DefaultWriteContractOptions} options.
76
94
  * @param {erc20PermitParam} [options.erc20PermitParam] The permit signature for token approval.
77
95
  * @param {boolean} [options.postOnly] A boolean indicating whether the order is only to be made not taken.
78
- * @param {string} [options.rpcUrl] The RPC URL of the blockchain.
79
- * @returns {Promise<{ transaction: Transaction, result: { make: CurrencyFlow, take: CurrencyFlow } }>}
96
+ * @param {bigint} [options.makeTick] The tick for the make order.
97
+ * @param {bigint} [options.takeLimitTick] The tick for the take order.
98
+ * @param {boolean} [options.roundingUpMakeBid] A boolean indicating whether to round up the make bid.
99
+ * @param {boolean} [options.roundingDownMakeAsk] A boolean indicating whether to round down the make ask.
100
+ * @param {boolean} [options.roundingDownTakenBid] A boolean indicating whether to round down the taken bid.
101
+ * @param {boolean} [options.roundingUpTakenAsk] A boolean indicating whether to round up the taken ask.
102
+ * @returns {Promise<{ transaction: Transaction, result: { make: CurrencyFlow, take: CurrencyFlow, spent: CurrencyFlow }>}
80
103
  * Promise resolving to the transaction object representing the limit order with the result of the order.
81
104
  * @example
82
- * import { signERC20Permit, limitOrder } from '@clober/v2-sdk'
105
+ * import { limitOrder } from '@clober/v2-sdk'
83
106
  * import { privateKeyToAccount } from 'viem/accounts'
84
107
  *
85
- * const erc20PermitParam = await signERC20Permit({
86
- * chainId: 421614,
87
- * walletClient,
88
- * token: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
89
- * amount: '100.123'
90
- * })
91
- *
92
108
  * const { transaction } = await limitOrder({
93
109
  * chainId: 421614,
94
110
  * userAddress: '0xF8c1869Ecd4df136693C45EcE1b67f85B6bDaE69
@@ -96,7 +112,6 @@ export const openMarket = decorator(async ({ chainId, inputToken, outputToken, o
96
112
  * outputToken: '0x0000000000000000000000000000000000000000',
97
113
  * amount: '100.123', // 100.123 USDC
98
114
  * price: '4000.01', // price at 4000.01 (ETH/USDC)
99
- * options: { erc20PermitParam }
100
115
  * })
101
116
  *
102
117
  * @example
@@ -111,13 +126,24 @@ export const openMarket = decorator(async ({ chainId, inputToken, outputToken, o
111
126
  * price: '4000.01', // price at 4000.01 (ETH/USDC)
112
127
  * })
113
128
  */
114
- export const limitOrder = decorator(async ({ chainId, userAddress, inputToken, outputToken, amount, price, options, }) => {
115
- const market = await fetchMarket(chainId, [inputToken, outputToken]);
129
+ export const limitOrder = async ({ chainId, userAddress, inputToken, outputToken, amount, price, options, }) => {
130
+ const [roundingUpMakeBid, roundingDownMakeAsk, roundingDownTakenBid, roundingUpTakenAsk,] = [
131
+ options?.roundingUpMakeBid ? options.roundingUpMakeBid : false,
132
+ options?.roundingDownMakeAsk ? options.roundingDownMakeAsk : false,
133
+ options?.roundingDownTakenBid ? options.roundingDownTakenBid : false,
134
+ options?.roundingUpTakenAsk ? options.roundingUpTakenAsk : false,
135
+ ];
136
+ const publicClient = createPublicClient({
137
+ chain: CHAIN_MAP[chainId],
138
+ transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
139
+ });
140
+ const market = await fetchMarket(publicClient, chainId, [inputToken, outputToken], !!(options && options.useSubgraph));
116
141
  const isBid = isAddressEqual(market.quote.address, inputToken);
117
142
  const [inputCurrency, outputCurrency] = isBid
118
143
  ? [market.quote, market.base]
119
144
  : [market.base, market.quote];
120
- if ((isBid && !market.bidBookOpen) || (!isBid && !market.askBookOpen)) {
145
+ if ((isBid && !market.bidBook.isOpened) ||
146
+ (!isBid && !market.askBook.isOpened)) {
121
147
  throw new Error(`
122
148
  Open the market before placing a limit order.
123
149
  import { openMarket } from '@clober/v2-sdk'
@@ -129,33 +155,36 @@ export const limitOrder = decorator(async ({ chainId, userAddress, inputToken, o
129
155
  })
130
156
  `);
131
157
  }
132
- const rawPrice = parsePrice(Number(price), market.quote.decimals, market.base.decimals);
133
- const tick = isBid ? fromPrice(rawPrice) : fromPrice(invertPrice(rawPrice));
158
+ const { roundingDownTick, roundingUpTick } = parsePrice(Number(price), market.quote.decimals, market.base.decimals);
134
159
  const tokensToSettle = [inputToken, outputToken].filter((address) => !isAddressEqual(address, zeroAddress));
135
160
  const quoteAmount = parseUnits(amount, inputCurrency.decimals);
136
- const [unit, { spendAmount, bookId }] = await Promise.all([
137
- calculateUnit(chainId, inputCurrency),
138
- getExpectedOutput({
139
- chainId,
140
- inputToken,
141
- outputToken,
142
- amountIn: amount,
143
- options: {
144
- ...options,
145
- limitPrice: price,
146
- },
147
- }),
148
- ]);
161
+ const unitSize = calculateUnitSize(chainId, inputCurrency);
162
+ const { takenAmount, spentAmount, bookId, events } = await getExpectedOutput({
163
+ chainId,
164
+ inputToken,
165
+ outputToken,
166
+ amountIn: amount,
167
+ options: {
168
+ ...options,
169
+ limitPrice: price,
170
+ },
171
+ });
149
172
  const isETH = isAddressEqual(inputToken, zeroAddress);
150
173
  const makeParam = {
151
- id: toBookId(inputToken, outputToken, unit),
152
- tick: Number(tick),
174
+ id: toBookId(chainId, inputToken, outputToken, unitSize),
175
+ tick: options?.makeTick
176
+ ? Number(options.makeTick)
177
+ : Number(isBid
178
+ ? roundingUpMakeBid
179
+ ? roundingUpTick
180
+ : roundingDownTick
181
+ : invertTick(roundingDownMakeAsk ? roundingDownTick : roundingUpTick)),
153
182
  quoteAmount,
154
183
  hookData: zeroHash,
155
184
  };
156
- if (options?.postOnly === true || spendAmount === '0') {
185
+ if (options?.postOnly === true || spentAmount === '0') {
157
186
  return {
158
- transaction: await buildTransaction(chainId, {
187
+ transaction: await buildTransaction(publicClient, {
159
188
  chain: CHAIN_MAP[chainId],
160
189
  account: userAddress,
161
190
  address: CONTRACT_ADDRESSES[chainId].Controller,
@@ -174,11 +203,21 @@ export const limitOrder = decorator(async ({ chainId, userAddress, inputToken, o
174
203
  amount: formatUnits(quoteAmount, inputCurrency.decimals),
175
204
  currency: inputCurrency,
176
205
  direction: 'in',
206
+ price: formatPrice(isBid
207
+ ? toPrice(BigInt(makeParam.tick))
208
+ : toPrice(invertTick(BigInt(makeParam.tick))), market.quote.decimals, market.base.decimals),
177
209
  },
178
- take: {
210
+ spent: {
211
+ amount: '0',
212
+ currency: inputCurrency,
213
+ direction: 'in',
214
+ events: [],
215
+ },
216
+ taken: {
179
217
  amount: '0',
180
218
  currency: outputCurrency,
181
219
  direction: 'out',
220
+ events: [],
182
221
  },
183
222
  },
184
223
  };
@@ -186,7 +225,7 @@ export const limitOrder = decorator(async ({ chainId, userAddress, inputToken, o
186
225
  else {
187
226
  // take and make
188
227
  return {
189
- transaction: await buildTransaction(chainId, {
228
+ transaction: await buildTransaction(publicClient, {
190
229
  chain: CHAIN_MAP[chainId],
191
230
  account: userAddress,
192
231
  address: CONTRACT_ADDRESSES[chainId].Controller,
@@ -197,7 +236,15 @@ export const limitOrder = decorator(async ({ chainId, userAddress, inputToken, o
197
236
  {
198
237
  takeBookId: bookId,
199
238
  makeBookId: makeParam.id,
200
- limitPrice: isBid ? invertPrice(rawPrice) : rawPrice,
239
+ limitPrice: options?.takeLimitTick
240
+ ? toPrice(options.takeLimitTick)
241
+ : toPrice(isBid
242
+ ? invertTick(roundingUpTakenAsk
243
+ ? roundingUpTick
244
+ : roundingDownTick)
245
+ : roundingDownTakenBid
246
+ ? roundingDownTick
247
+ : roundingUpTick),
201
248
  tick: makeParam.tick,
202
249
  quoteAmount,
203
250
  takeHookData: zeroHash,
@@ -212,23 +259,39 @@ export const limitOrder = decorator(async ({ chainId, userAddress, inputToken, o
212
259
  }, options?.gasLimit),
213
260
  result: {
214
261
  make: {
215
- amount: formatUnits(quoteAmount, inputCurrency.decimals),
262
+ amount: formatUnits(quoteAmount - parseUnits(spentAmount, inputCurrency.decimals), inputCurrency.decimals),
216
263
  currency: inputCurrency,
217
264
  direction: 'in',
265
+ price: formatPrice(isBid
266
+ ? toPrice(BigInt(makeParam.tick))
267
+ : toPrice(invertTick(BigInt(makeParam.tick))), market.quote.decimals, market.base.decimals),
218
268
  },
219
- take: {
220
- amount: spendAmount,
269
+ spent: {
270
+ amount: spentAmount,
271
+ currency: inputCurrency,
272
+ direction: 'in',
273
+ events: events.map(({ price, spentAmount }) => ({
274
+ price,
275
+ amount: spentAmount,
276
+ })),
277
+ },
278
+ taken: {
279
+ amount: takenAmount,
221
280
  currency: outputCurrency,
222
281
  direction: 'out',
282
+ events: events.map(({ price, takenAmount }) => ({
283
+ price,
284
+ amount: takenAmount,
285
+ })),
223
286
  },
224
287
  },
225
288
  };
226
289
  }
227
- });
290
+ };
228
291
  /**
229
292
  * Executes a market order on the specified chain for trading tokens.
230
293
  * If only `amountIn` is provided, spend the specified amount of input tokens.
231
- * If `amountIn` and `amountOut` are provided, take the appropriate amount of output tokens with the specified input amount.
294
+ * If only `amountOut` is provided, take the specified amount of output tokens.
232
295
  *
233
296
  * @param {CHAIN_IDS} chainId The chain ID.
234
297
  * @param {`0x${string}`} userAddress The Ethereum address of the user placing the order.
@@ -236,24 +299,18 @@ export const limitOrder = decorator(async ({ chainId, userAddress, inputToken, o
236
299
  * @param {`0x${string}`} outputToken The address of the token to be received as output.
237
300
  * @param {string} amountIn The amount of input tokens for the order to spend.
238
301
  * @param {string} amountOut The amount of output tokens for the order to take.
239
- * @param {Object} [options] Optional parameters for the market order.
302
+ * @param options {@link DefaultWriteContractOptions} options.
240
303
  * @param {erc20PermitParam} [options.erc20PermitParam] The permit signature for token approval.
241
- * @param {string} [options.rpcUrl] The RPC URL of the blockchain.
242
304
  * @param {number} [options.slippage] The maximum slippage percentage allowed for the order.
305
+ * @param {boolean} [options.roundingDownTakenBid] A boolean indicating whether to round down the taken bid.
306
+ * @param {boolean} [options.roundingUpTakenAsk] A boolean indicating whether to round up the taken ask.
243
307
  * if the slippage is not provided, unlimited slippage is allowed.
244
- * @returns {Promise<{ transaction: Transaction, result: { spend: CurrencyFlow, take: CurrencyFlow } }>}
308
+ * @returns {Promise<{ transaction: Transaction, result: { spent: CurrencyFlow, taken: CurrencyFlow } }>}
245
309
  * Promise resolving to the transaction object representing the market order with the result of the order.
246
310
  * @example
247
- * import { signERC20Permit, marketOrder } from '@clober/v2-sdk'
311
+ * import { marketOrder } from '@clober/v2-sdk'
248
312
  * import { privateKeyToAccount } from 'viem/accounts'
249
313
  *
250
- * const erc20PermitParam = await signERC20Permit({
251
- * chainId: 421614,
252
- * walletClient,
253
- * token: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
254
- * amount: '100.123'
255
- * })
256
- *
257
314
  * const transaction = await marketOrder({
258
315
  * chainId: 421614,
259
316
  * userAddress: '0xF8c1869Ecd4df136693C45EcE1b67f85B6bDaE69
@@ -264,14 +321,24 @@ export const limitOrder = decorator(async ({ chainId, userAddress, inputToken, o
264
321
  * })
265
322
  *
266
323
  */
267
- export const marketOrder = decorator(async ({ chainId, userAddress, inputToken, outputToken, amountIn, amountOut, options, }) => {
268
- const market = await fetchMarket(chainId, [inputToken, outputToken]);
324
+ export const marketOrder = async ({ chainId, userAddress, inputToken, outputToken, amountIn, amountOut, options, }) => {
325
+ if (!amountIn && !amountOut) {
326
+ throw new Error('Either amountIn or amountOut must be provided');
327
+ }
328
+ else if (amountIn && amountOut) {
329
+ throw new Error('Only one of amountIn or amountOut can be provided');
330
+ }
331
+ const publicClient = createPublicClient({
332
+ chain: CHAIN_MAP[chainId],
333
+ transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
334
+ });
335
+ const market = await fetchMarket(publicClient, chainId, [inputToken, outputToken], !!(options && options.useSubgraph));
269
336
  const isTakingBid = isAddressEqual(market.base.address, inputToken);
270
337
  const [inputCurrency, outputCurrency] = isTakingBid
271
338
  ? [market.base, market.quote]
272
339
  : [market.quote, market.base];
273
- if ((isTakingBid && !market.bidBookOpen) ||
274
- (!isTakingBid && !market.askBookOpen)) {
340
+ if ((isTakingBid && !market.bidBook.isOpened) ||
341
+ (!isTakingBid && !market.askBook.isOpened)) {
275
342
  throw new Error(`
276
343
  Open the market before placing a market order.
277
344
  import { openMarket } from '@clober/v2-sdk'
@@ -286,7 +353,7 @@ export const marketOrder = decorator(async ({ chainId, userAddress, inputToken,
286
353
  const tokensToSettle = [inputToken, outputToken].filter((address) => !isAddressEqual(address, zeroAddress));
287
354
  const isETH = isAddressEqual(inputToken, zeroAddress);
288
355
  if (amountIn && !amountOut) {
289
- const { bookId, takenAmount, spendAmount } = await getExpectedOutput({
356
+ const { bookId, takenAmount, spentAmount, events } = await getExpectedOutput({
290
357
  chainId,
291
358
  inputToken,
292
359
  outputToken,
@@ -298,7 +365,7 @@ export const marketOrder = decorator(async ({ chainId, userAddress, inputToken,
298
365
  });
299
366
  const baseAmount = parseUnits(amountIn, inputCurrency.decimals);
300
367
  return {
301
- transaction: await buildTransaction(chainId, {
368
+ transaction: await buildTransaction(publicClient, {
302
369
  chain: CHAIN_MAP[chainId],
303
370
  account: userAddress,
304
371
  address: CONTRACT_ADDRESSES[chainId].Controller,
@@ -323,21 +390,29 @@ export const marketOrder = decorator(async ({ chainId, userAddress, inputToken,
323
390
  value: isETH ? baseAmount : 0n,
324
391
  }, options?.gasLimit),
325
392
  result: {
326
- spend: {
327
- amount: spendAmount,
393
+ spent: {
394
+ amount: spentAmount,
328
395
  currency: inputCurrency,
329
396
  direction: 'in',
397
+ events: events.map(({ price, spentAmount }) => ({
398
+ price,
399
+ amount: spentAmount,
400
+ })),
330
401
  },
331
- take: {
402
+ taken: {
332
403
  amount: takenAmount,
333
404
  currency: outputCurrency,
334
405
  direction: 'out',
406
+ events: events.map(({ price, takenAmount }) => ({
407
+ price,
408
+ amount: takenAmount,
409
+ })),
335
410
  },
336
411
  },
337
412
  };
338
413
  }
339
- else if (amountIn && amountOut) {
340
- const { bookId, spendAmount, takenAmount } = await getExpectedInput({
414
+ else if (!amountIn && amountOut) {
415
+ const { bookId, spentAmount, takenAmount, events } = await getExpectedInput({
341
416
  chainId,
342
417
  inputToken,
343
418
  outputToken,
@@ -348,9 +423,15 @@ export const marketOrder = decorator(async ({ chainId, userAddress, inputToken,
348
423
  },
349
424
  });
350
425
  const quoteAmount = parseUnits(amountOut, outputCurrency.decimals);
351
- const baseAmount = parseUnits(amountIn ?? spendAmount, inputCurrency.decimals);
426
+ const baseAmount = parseUnits(spentAmount, inputCurrency.decimals);
427
+ const maxBaseAmount = options?.erc20PermitParam?.permitAmount ??
428
+ (options?.slippage
429
+ ? applyPercent(baseAmount, 100 + options.slippage)
430
+ : isETH
431
+ ? baseAmount
432
+ : 2n ** 256n - 1n);
352
433
  return {
353
- transaction: await buildTransaction(chainId, {
434
+ transaction: await buildTransaction(publicClient, {
354
435
  chain: CHAIN_MAP[chainId],
355
436
  account: userAddress,
356
437
  address: CONTRACT_ADDRESSES[chainId].Controller,
@@ -362,9 +443,7 @@ export const marketOrder = decorator(async ({ chainId, userAddress, inputToken,
362
443
  id: bookId,
363
444
  limitPrice: 0n,
364
445
  quoteAmount,
365
- maxBaseAmount: options?.slippage
366
- ? applyPercent(baseAmount, 100 + options.slippage)
367
- : 2n ** 256n - 1n,
446
+ maxBaseAmount,
368
447
  hookData: zeroHash,
369
448
  },
370
449
  ],
@@ -372,18 +451,26 @@ export const marketOrder = decorator(async ({ chainId, userAddress, inputToken,
372
451
  options?.erc20PermitParam ? [options.erc20PermitParam] : [],
373
452
  getDeadlineTimestampInSeconds(),
374
453
  ],
375
- value: isETH ? baseAmount : 0n,
454
+ value: isETH ? maxBaseAmount : 0n,
376
455
  }, options?.gasLimit),
377
456
  result: {
378
- spend: {
379
- amount: spendAmount,
457
+ spent: {
458
+ amount: spentAmount,
380
459
  currency: inputCurrency,
381
460
  direction: 'in',
461
+ events: events.map(({ price, spentAmount }) => ({
462
+ price,
463
+ amount: spentAmount,
464
+ })),
382
465
  },
383
- take: {
466
+ taken: {
384
467
  amount: takenAmount,
385
468
  currency: outputCurrency,
386
469
  direction: 'out',
470
+ events: events.map(({ price, takenAmount }) => ({
471
+ price,
472
+ amount: takenAmount,
473
+ })),
387
474
  },
388
475
  },
389
476
  };
@@ -391,7 +478,7 @@ export const marketOrder = decorator(async ({ chainId, userAddress, inputToken,
391
478
  else {
392
479
  throw new Error('Either amountIn or amountOut must be provided');
393
480
  }
394
- });
481
+ };
395
482
  /**
396
483
  * Claims specified open order for settlement.
397
484
  * [IMPORTANT] Set ApprovalForAll before calling this function.
@@ -399,8 +486,7 @@ export const marketOrder = decorator(async ({ chainId, userAddress, inputToken,
399
486
  * @param {CHAIN_IDS} chainId The chain ID.
400
487
  * @param {`0x${string}`} userAddress The Ethereum address of the user.
401
488
  * @param {string} id An ID representing the open order to be claimed.
402
- * @param {Object} [options] Optional parameters for claiming orders.
403
- * @param {string} [options.rpcUrl] The RPC URL to use for executing the transaction.
489
+ * @param options {@link DefaultWriteContractOptions} options.
404
490
  * @returns {Promise<{ transaction: Transaction, result: CurrencyFlow }>}
405
491
  * Promise resolving to the transaction object representing the claim action with the result of the order.
406
492
  * @throws {Error} Throws an error if no open orders are found for the specified user.
@@ -417,7 +503,7 @@ export const marketOrder = decorator(async ({ chainId, userAddress, inputToken,
417
503
  * id: openOrders.map((order) => order.id)
418
504
  * })
419
505
  */
420
- export const claimOrder = decorator(async ({ chainId, userAddress, id, options, }) => {
506
+ export const claimOrder = async ({ chainId, userAddress, id, options, }) => {
421
507
  const { transaction, result } = await claimOrders({
422
508
  chainId,
423
509
  userAddress,
@@ -428,7 +514,7 @@ export const claimOrder = decorator(async ({ chainId, userAddress, id, options,
428
514
  transaction,
429
515
  result: result[0],
430
516
  };
431
- });
517
+ };
432
518
  /**
433
519
  * Claims specified open orders for settlement.
434
520
  * [IMPORTANT] Set ApprovalForAll before calling this function.
@@ -436,8 +522,7 @@ export const claimOrder = decorator(async ({ chainId, userAddress, id, options,
436
522
  * @param {CHAIN_IDS} chainId The chain ID.
437
523
  * @param {`0x${string}`} userAddress The Ethereum address of the user.
438
524
  * @param {string[]} ids An array of IDs representing the open orders to be claimed.
439
- * @param {Object} [options] Optional parameters for claiming orders.
440
- * @param {string} [options.rpcUrl] The RPC URL to use for executing the transaction.
525
+ * @param options {@link DefaultWriteContractOptions} options.
441
526
  * @returns {Promise<{ transaction: Transaction, result: CurrencyFlow[] }>}
442
527
  * Promise resolving to the transaction object representing the claim action with the result of the orders.
443
528
  * @throws {Error} Throws an error if no open orders are found for the specified user.
@@ -454,8 +539,12 @@ export const claimOrder = decorator(async ({ chainId, userAddress, id, options,
454
539
  * ids: openOrders.map((order) => order.id)
455
540
  * )
456
541
  */
457
- export const claimOrders = decorator(async ({ chainId, userAddress, ids, options, }) => {
458
- const isApprovedForAll = await fetchIsApprovedForAll(chainId, userAddress);
542
+ export const claimOrders = async ({ chainId, userAddress, ids, options, }) => {
543
+ const publicClient = createPublicClient({
544
+ chain: CHAIN_MAP[chainId],
545
+ transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
546
+ });
547
+ const isApprovedForAll = await fetchIsApprovedForAll(publicClient, chainId, userAddress);
459
548
  if (!isApprovedForAll) {
460
549
  throw new Error(`
461
550
  Set ApprovalForAll before calling this function.
@@ -467,22 +556,25 @@ export const claimOrders = decorator(async ({ chainId, userAddress, ids, options
467
556
  })
468
557
  `);
469
558
  }
470
- const orders = (await fetchOrders(chainId, ids.map((id) => BigInt(id)))).filter((order) => isAddressEqual(order.owner, userAddress) && order.claimable > 0n);
559
+ const useSubgraph = !!(options && options.useSubgraph);
560
+ const orders = (useSubgraph
561
+ ? await fetchOpenOrdersByOrderIdsFromSubgraph(chainId, ids)
562
+ : await fetchOnChainOrders(publicClient, chainId, ids.map((id) => BigInt(id)))).filter((order) => isAddressEqual(order.user, userAddress) && order.claimable.value !== '0');
471
563
  const tokensToSettle = orders
472
- .map((order) => [order.baseCurrency.address, order.quoteCurrency.address])
564
+ .map((order) => [order.inputCurrency.address, order.outputCurrency.address])
473
565
  .flat()
474
566
  .filter((address, index, self) => self.findIndex((c) => isAddressEqual(c, address)) === index)
475
567
  .filter((address) => !isAddressEqual(address, zeroAddress));
476
568
  return {
477
- transaction: await buildTransaction(chainId, {
569
+ transaction: await buildTransaction(publicClient, {
478
570
  chain: CHAIN_MAP[chainId],
479
571
  account: userAddress,
480
572
  address: CONTRACT_ADDRESSES[chainId].Controller,
481
573
  abi: CONTROLLER_ABI,
482
574
  functionName: 'claim',
483
575
  args: [
484
- orders.map(({ orderId }) => ({
485
- id: orderId,
576
+ orders.map(({ id }) => ({
577
+ id,
486
578
  hookData: zeroHash,
487
579
  })),
488
580
  tokensToSettle,
@@ -490,24 +582,16 @@ export const claimOrders = decorator(async ({ chainId, userAddress, ids, options
490
582
  getDeadlineTimestampInSeconds(),
491
583
  ],
492
584
  }, options?.gasLimit),
493
- result: orders
494
- .map((order) => {
495
- const amount = quoteToBase(order.tick, order.unit * order.claimable, false);
496
- return {
497
- currency: order.baseCurrency,
498
- amount: formatUnits(amount, order.baseCurrency.decimals),
499
- };
500
- })
501
- .reduce((acc, { currency, amount }) => {
585
+ result: orders.reduce((acc, { claimable: { currency, value } }) => {
502
586
  const index = acc.findIndex((c) => isAddressEqual(c.currency.address, currency.address));
503
587
  if (index === -1) {
504
- return [...acc, { currency, amount, direction: 'out' }];
588
+ return [...acc, { currency, amount: value, direction: 'out' }];
505
589
  }
506
- acc[index].amount = (Number(acc[index].amount) + Number(amount)).toString();
590
+ acc[index].amount = (Number(acc[index].amount) + Number(value)).toString();
507
591
  return acc;
508
592
  }, []),
509
593
  };
510
- });
594
+ };
511
595
  /**
512
596
  * Cancels specified open order if the order is not fully filled.
513
597
  * [IMPORTANT] Set ApprovalForAll before calling this function.
@@ -515,8 +599,7 @@ export const claimOrders = decorator(async ({ chainId, userAddress, ids, options
515
599
  * @param {CHAIN_IDS} chainId The chain ID.
516
600
  * @param {`0x${string}`} userAddress The Ethereum address of the user.
517
601
  * @param {string} id An ID representing the open order to be canceled
518
- * @param {Object} [options] Optional parameters for canceling orders.
519
- * @param {string} [options.rpcUrl] The RPC URL to use for executing the transaction.
602
+ * @param options {@link DefaultWriteContractOptions} options.
520
603
  * @returns {Promise<{ transaction: Transaction, result: CurrencyFlow }>}
521
604
  * Promise resolving to the transaction object representing the cancel action with the result of the order.
522
605
  * @throws {Error} Throws an error if no open orders are found for the specified user.
@@ -533,7 +616,7 @@ export const claimOrders = decorator(async ({ chainId, userAddress, ids, options
533
616
  * id: openOrders.map((order) => order.id)
534
617
  * })
535
618
  */
536
- export const cancelOrder = decorator(async ({ chainId, userAddress, id, options, }) => {
619
+ export const cancelOrder = async ({ chainId, userAddress, id, options, }) => {
537
620
  const { transaction, result } = await cancelOrders({
538
621
  chainId,
539
622
  userAddress,
@@ -544,7 +627,7 @@ export const cancelOrder = decorator(async ({ chainId, userAddress, id, options,
544
627
  transaction,
545
628
  result: result[0],
546
629
  };
547
- });
630
+ };
548
631
  /**
549
632
  * Cancels specified open orders if orders are not fully filled.
550
633
  * [IMPORTANT] Set ApprovalForAll before calling this function.
@@ -552,8 +635,7 @@ export const cancelOrder = decorator(async ({ chainId, userAddress, id, options,
552
635
  * @param {CHAIN_IDS} chainId The chain ID.
553
636
  * @param {`0x${string}`} userAddress The Ethereum address of the user.
554
637
  * @param {string[]} ids An array of IDs representing the open orders to be canceled.
555
- * @param {Object} [options] Optional parameters for canceling orders.
556
- * @param {string} [options.rpcUrl] The RPC URL to use for executing the transaction.
638
+ * @param options {@link DefaultWriteContractOptions} options.
557
639
  * @returns {Promise<{ transaction: Transaction, result: CurrencyFlow[] }>
558
640
  * Promise resolving to the transaction object representing the cancel action with the result of the orders.
559
641
  * @throws {Error} Throws an error if no open orders are found for the specified user.
@@ -570,8 +652,12 @@ export const cancelOrder = decorator(async ({ chainId, userAddress, id, options,
570
652
  * ids: openOrders.map((order) => order.id)
571
653
  * })
572
654
  */
573
- export const cancelOrders = decorator(async ({ chainId, userAddress, ids, options, }) => {
574
- const isApprovedForAll = await fetchIsApprovedForAll(chainId, userAddress);
655
+ export const cancelOrders = async ({ chainId, userAddress, ids, options, }) => {
656
+ const publicClient = createPublicClient({
657
+ chain: CHAIN_MAP[chainId],
658
+ transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
659
+ });
660
+ const isApprovedForAll = await fetchIsApprovedForAll(publicClient, chainId, userAddress);
575
661
  if (!isApprovedForAll) {
576
662
  throw new Error(`
577
663
  Set ApprovalForAll before calling this function.
@@ -583,22 +669,25 @@ export const cancelOrders = decorator(async ({ chainId, userAddress, ids, option
583
669
  })
584
670
  `);
585
671
  }
586
- const orders = (await fetchOrders(chainId, ids.map((id) => BigInt(id)))).filter((order) => isAddressEqual(order.owner, userAddress) && order.open > 0n);
672
+ const useSubgraph = !!(options && options.useSubgraph);
673
+ const orders = (useSubgraph
674
+ ? await fetchOpenOrdersByOrderIdsFromSubgraph(chainId, ids)
675
+ : await fetchOnChainOrders(publicClient, chainId, ids.map((id) => BigInt(id)))).filter((order) => isAddressEqual(order.user, userAddress) && order.cancelable.value !== '0');
587
676
  const tokensToSettle = orders
588
- .map((order) => [order.baseCurrency.address, order.quoteCurrency.address])
677
+ .map((order) => [order.inputCurrency.address, order.outputCurrency.address])
589
678
  .flat()
590
679
  .filter((address, index, self) => self.findIndex((c) => isAddressEqual(c, address)) === index)
591
680
  .filter((address) => !isAddressEqual(address, zeroAddress));
592
681
  return {
593
- transaction: await buildTransaction(chainId, {
682
+ transaction: await buildTransaction(publicClient, {
594
683
  chain: CHAIN_MAP[chainId],
595
684
  account: userAddress,
596
685
  address: CONTRACT_ADDRESSES[chainId].Controller,
597
686
  abi: CONTROLLER_ABI,
598
687
  functionName: 'cancel',
599
688
  args: [
600
- orders.map(({ orderId }) => ({
601
- id: orderId,
689
+ orders.map(({ id }) => ({
690
+ id,
602
691
  leftQuoteAmount: 0n,
603
692
  hookData: zeroHash,
604
693
  })),
@@ -607,24 +696,562 @@ export const cancelOrders = decorator(async ({ chainId, userAddress, ids, option
607
696
  getDeadlineTimestampInSeconds(),
608
697
  ],
609
698
  }, options?.gasLimit),
610
- result: orders
611
- .map((order) => {
612
- const amount = applyPercent(order.unit * order.open, 100 +
613
- (Number(MAKER_DEFAULT_POLICY.rate) * 100) /
614
- Number(MAKER_DEFAULT_POLICY.RATE_PRECISION), 6);
615
- return {
616
- currency: order.quoteCurrency,
617
- amount: formatUnits(amount, order.quoteCurrency.decimals),
618
- };
619
- })
620
- .reduce((acc, { currency, amount }) => {
699
+ result: orders.reduce((acc, { cancelable: { currency, value } }) => {
621
700
  const index = acc.findIndex((c) => isAddressEqual(c.currency.address, currency.address));
622
701
  if (index === -1) {
623
- return [...acc, { currency, amount, direction: 'out' }];
702
+ return [...acc, { currency, amount: value, direction: 'out' }];
624
703
  }
625
- acc[index].amount = (Number(acc[index].amount) + Number(amount)).toString();
704
+ acc[index].amount = (Number(acc[index].amount) + Number(value)).toString();
626
705
  return acc;
627
706
  }, []),
628
707
  };
629
- });
708
+ };
709
+ /**
710
+ * Build a transaction to open a pool,
711
+ *
712
+ * @param chainId The chain ID of the blockchain.
713
+ * @param userAddress The address of the user.
714
+ * @param inputToken The address of the input token.
715
+ * @param outputToken The address of the output token.
716
+ * @param options {@link DefaultWriteContractOptions} options.
717
+ * @returns A Promise resolving to a transaction object. If the market is already open, returns undefined.
718
+ * @example
719
+ * import { openPool } from '@clober/v2-sdk'
720
+ *
721
+ * const transaction = await openPool({
722
+ * chainId: 421614,
723
+ * userAddress: '0xF8c1869Ecd4df136693C45EcE1b67f85B6bDaE69',
724
+ * inputToken: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
725
+ * outputToken: '0x0000000000000000000000000000000000000000',
726
+ * salt: '0x0000000000000000000000000000000000000000000000000000000000000000',
727
+ * })
728
+ */
729
+ export const openPool = async ({ chainId, userAddress, tokenA, tokenB, salt, options, }) => {
730
+ const publicClient = createPublicClient({
731
+ chain: CHAIN_MAP[chainId],
732
+ transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
733
+ });
734
+ const pool = await fetchPool(publicClient, chainId, [tokenA, tokenB], salt, !!(options && options.useSubgraph));
735
+ if (!pool.isOpened) {
736
+ return buildTransaction(publicClient, {
737
+ chain: CHAIN_MAP[chainId],
738
+ address: CONTRACT_ADDRESSES[chainId].Rebalancer,
739
+ account: userAddress,
740
+ abi: REBALANCER_ABI,
741
+ functionName: 'open',
742
+ args: [
743
+ {
744
+ base: pool.market.bidBook.base.address,
745
+ unitSize: pool.market.bidBook.unitSize,
746
+ quote: pool.market.bidBook.quote.address,
747
+ makerPolicy: MAKER_DEFAULT_POLICY[chainId].value,
748
+ hooks: zeroAddress,
749
+ takerPolicy: TAKER_DEFAULT_POLICY[chainId].value,
750
+ },
751
+ {
752
+ base: pool.market.askBook.base.address,
753
+ unitSize: pool.market.askBook.unitSize,
754
+ quote: pool.market.askBook.quote.address,
755
+ makerPolicy: MAKER_DEFAULT_POLICY[chainId].value,
756
+ hooks: zeroAddress,
757
+ takerPolicy: TAKER_DEFAULT_POLICY[chainId].value,
758
+ },
759
+ toBytes32(salt),
760
+ CONTRACT_ADDRESSES[chainId].Strategy,
761
+ ],
762
+ }, options?.gasLimit);
763
+ }
764
+ return undefined;
765
+ };
766
+ export const addLiquidity = async ({ chainId, userAddress, token0, token1, salt, amount0, amount1, options, }) => {
767
+ const publicClient = createPublicClient({
768
+ chain: CHAIN_MAP[chainId],
769
+ transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
770
+ });
771
+ const pool = await fetchPool(publicClient, chainId, [token0, token1], salt, !!(options && options.useSubgraph));
772
+ if (!pool.isOpened) {
773
+ throw new Error(`
774
+ Open the pool before adding liquidity.
775
+ import { openPool } from '@clober/v2-sdk'
776
+
777
+ const transaction = await openPool({
778
+ chainId: ${chainId},
779
+ tokenA: '${token0}',
780
+ tokenB: '${token1}',
781
+ salt: '0x0000000000000000000000000000000000000000000000000000000000000000',
782
+ })
783
+ `);
784
+ }
785
+ const [amountAOrigin, amountBOrigin] = isAddressEqual(pool.currencyA.address, getAddress(token0))
786
+ ? [
787
+ parseUnits(amount0 ?? '0', pool.currencyA.decimals),
788
+ parseUnits(amount1 ?? '0', pool.currencyB.decimals),
789
+ ]
790
+ : [
791
+ parseUnits(amount1 ?? '0', pool.currencyA.decimals),
792
+ parseUnits(amount0 ?? '0', pool.currencyB.decimals),
793
+ ];
794
+ let [amountA, amountB] = [amountAOrigin, amountBOrigin];
795
+ const tokenAPermitParams = isAddressEqual(pool.currencyA.address, getAddress(token0))
796
+ ? options?.token0PermitParams ?? emptyERC20PermitParams
797
+ : options?.token1PermitParams ?? emptyERC20PermitParams;
798
+ const tokenBPermitParams = isAddressEqual(pool.currencyA.address, getAddress(token0))
799
+ ? options?.token1PermitParams ?? emptyERC20PermitParams
800
+ : options?.token0PermitParams ?? emptyERC20PermitParams;
801
+ let disableSwap = !!(options && options.disableSwap);
802
+ if (pool.totalSupply === 0n ||
803
+ (pool.liquidityA === 0n && pool.liquidityB === 0n)) {
804
+ disableSwap = true;
805
+ }
806
+ const slippageLimitPercent = options?.slippage ?? 1.0;
807
+ const swapParams = {
808
+ inCurrency: zeroAddress,
809
+ amount: 0n,
810
+ data: '0x',
811
+ };
812
+ if (!disableSwap) {
813
+ const currencyBPerCurrencyA = options?.testnetPrice
814
+ ? isAddressEqual(getQuoteToken({
815
+ chainId,
816
+ token0,
817
+ token1,
818
+ }), pool.currencyA.address)
819
+ ? 1 / Number(options.testnetPrice)
820
+ : Number(options.testnetPrice)
821
+ : undefined;
822
+ const swapAmountA = parseUnits('1', pool.currencyA.decimals);
823
+ let swapAmountB = -1n;
824
+ if (options && options.token0Price && options.token1Price) {
825
+ const tokenAPrice = isAddressEqual(pool.currencyA.address, getAddress(token0))
826
+ ? options.token0Price
827
+ : options.token1Price;
828
+ const tokenBPrice = isAddressEqual(pool.currencyA.address, getAddress(token0))
829
+ ? options.token1Price
830
+ : options.token0Price;
831
+ swapAmountB = quotes(swapAmountA, tokenAPrice, tokenBPrice, pool.currencyA.decimals, pool.currencyB.decimals);
832
+ }
833
+ else {
834
+ ;
835
+ ({ amountOut: swapAmountB } = await fetchQuote({
836
+ chainId,
837
+ amountIn: swapAmountA,
838
+ tokenIn: pool.currencyA,
839
+ tokenOut: pool.currencyB,
840
+ slippageLimitPercent: 1,
841
+ userAddress: CONTRACT_ADDRESSES[chainId].Minter,
842
+ testnetPrice: currencyBPerCurrencyA,
843
+ }));
844
+ }
845
+ if (swapAmountB === -1n) {
846
+ throw new Error('Failed to fetch quote');
847
+ }
848
+ const { deltaA, deltaB } = getIdealDelta(amountA, amountB, pool.liquidityA, pool.liquidityB, swapAmountA, swapAmountB);
849
+ if (deltaA < 0n) {
850
+ swapParams.inCurrency = pool.currencyA.address;
851
+ swapParams.amount = -deltaA;
852
+ const { amountOut: actualDeltaB, data: calldata } = await fetchCallData({
853
+ chainId,
854
+ amountIn: swapParams.amount,
855
+ tokenIn: pool.currencyA,
856
+ tokenOut: pool.currencyB,
857
+ slippageLimitPercent,
858
+ userAddress: CONTRACT_ADDRESSES[chainId].Minter,
859
+ testnetPrice: currencyBPerCurrencyA,
860
+ });
861
+ swapParams.data = calldata;
862
+ amountA += deltaA;
863
+ amountB += actualDeltaB;
864
+ }
865
+ else if (deltaB < 0n) {
866
+ swapParams.inCurrency = pool.currencyB.address;
867
+ swapParams.amount = -deltaB;
868
+ const { amountOut: actualDeltaA, data: calldata } = await fetchCallData({
869
+ chainId,
870
+ amountIn: swapParams.amount,
871
+ tokenIn: pool.currencyB,
872
+ tokenOut: pool.currencyA,
873
+ slippageLimitPercent,
874
+ userAddress: CONTRACT_ADDRESSES[chainId].Minter,
875
+ testnetPrice: currencyBPerCurrencyA
876
+ ? 1 / currencyBPerCurrencyA
877
+ : undefined,
878
+ });
879
+ swapParams.data = calldata;
880
+ amountA += actualDeltaA;
881
+ amountB += deltaB;
882
+ }
883
+ }
884
+ const { mintAmount, inAmountA, inAmountB } = getExpectedMintResult(pool.totalSupply, pool.liquidityA, pool.liquidityB, amountA, amountB, pool.currencyA, pool.currencyB);
885
+ if (mintAmount === 0n) {
886
+ return {
887
+ transaction: undefined,
888
+ result: {
889
+ currencyA: {
890
+ currency: pool.currencyA,
891
+ amount: '0',
892
+ direction: 'in',
893
+ },
894
+ currencyB: {
895
+ currency: pool.currencyB,
896
+ amount: '0',
897
+ direction: 'in',
898
+ },
899
+ lpCurrency: {
900
+ currency: pool.currencyLp,
901
+ amount: '0',
902
+ direction: 'out',
903
+ },
904
+ },
905
+ };
906
+ }
907
+ const minMintAmount = applyPercent(mintAmount, 100 - slippageLimitPercent);
908
+ const transaction = await buildTransaction(publicClient, {
909
+ chain: CHAIN_MAP[chainId],
910
+ account: userAddress,
911
+ address: CONTRACT_ADDRESSES[chainId].Minter,
912
+ abi: MINTER_ABI,
913
+ functionName: 'mint',
914
+ args: [
915
+ pool.key,
916
+ amountAOrigin,
917
+ amountBOrigin,
918
+ minMintAmount,
919
+ {
920
+ permitAmount: tokenAPermitParams.permitAmount,
921
+ signature: tokenAPermitParams.signature,
922
+ },
923
+ {
924
+ permitAmount: tokenBPermitParams.permitAmount,
925
+ signature: tokenBPermitParams.signature,
926
+ },
927
+ swapParams,
928
+ ],
929
+ value: isAddressEqual(token0, zeroAddress)
930
+ ? amountAOrigin
931
+ : isAddressEqual(token1, zeroAddress)
932
+ ? amountBOrigin
933
+ : undefined,
934
+ }, options?.gasLimit);
935
+ const currencyARefund = amountA - inAmountA;
936
+ const currencyBRefund = amountB - inAmountB;
937
+ const currencyAResultAmount = amountAOrigin - currencyARefund;
938
+ const currencyBResultAmount = amountBOrigin - currencyBRefund;
939
+ return {
940
+ transaction,
941
+ result: {
942
+ currencyA: {
943
+ currency: pool.currencyA,
944
+ amount: formatUnits(abs(currencyAResultAmount), pool.currencyA.decimals),
945
+ direction: currencyAResultAmount >= 0 ? 'in' : 'out',
946
+ },
947
+ currencyB: {
948
+ currency: pool.currencyB,
949
+ amount: formatUnits(abs(currencyBResultAmount), pool.currencyB.decimals),
950
+ direction: currencyBResultAmount >= 0 ? 'in' : 'out',
951
+ },
952
+ lpCurrency: {
953
+ currency: pool.currencyLp,
954
+ amount: formatUnits(mintAmount, pool.currencyLp.decimals),
955
+ direction: 'out',
956
+ },
957
+ },
958
+ };
959
+ };
960
+ // @dev: Withdraw amount calculation logic is based on the contract code.
961
+ export const removeLiquidity = async ({ chainId, userAddress, token0, token1, salt, amount, options, }) => {
962
+ const publicClient = createPublicClient({
963
+ chain: CHAIN_MAP[chainId],
964
+ transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
965
+ });
966
+ const pool = await fetchPool(publicClient, chainId, [token0, token1], salt, !!(options && options.useSubgraph));
967
+ if (!pool.isOpened) {
968
+ throw new Error(`
969
+ Open the pool before removing liquidity.
970
+ import { openPool } from '@clober/v2-sdk'
971
+
972
+ const transaction = await openPool({
973
+ chainId: ${chainId},
974
+ tokenA: '${token0}',
975
+ tokenB: '${token1}',
976
+ salt: '0x0000000000000000000000000000000000000000000000000000000000000000',
977
+ })
978
+ `);
979
+ }
980
+ const burnAmount = parseUnits(amount, pool.currencyLp.decimals);
981
+ const slippageLimitPercent = options?.slippage ?? 2;
982
+ const withdrawAmountA = (burnAmount * pool.liquidityA) / pool.totalSupply;
983
+ const withdrawAmountB = (burnAmount * pool.liquidityB) / pool.totalSupply;
984
+ const minWithdrawAmountA = applyPercent(withdrawAmountA, 100 - slippageLimitPercent);
985
+ const minWithdrawAmountB = applyPercent(withdrawAmountB, 100 - slippageLimitPercent);
986
+ if (burnAmount === 0n) {
987
+ return {
988
+ transaction: undefined,
989
+ result: {
990
+ currencyA: {
991
+ currency: pool.currencyA,
992
+ amount: '0',
993
+ direction: 'out',
994
+ },
995
+ currencyB: {
996
+ currency: pool.currencyB,
997
+ amount: '0',
998
+ direction: 'out',
999
+ },
1000
+ lpCurrency: {
1001
+ currency: pool.currencyLp,
1002
+ amount: '0',
1003
+ direction: 'in',
1004
+ },
1005
+ },
1006
+ };
1007
+ }
1008
+ const transaction = await buildTransaction(publicClient, {
1009
+ chain: CHAIN_MAP[chainId],
1010
+ account: userAddress,
1011
+ address: CONTRACT_ADDRESSES[chainId].Rebalancer,
1012
+ abi: REBALANCER_ABI,
1013
+ functionName: 'burn',
1014
+ args: [pool.key, burnAmount, minWithdrawAmountA, minWithdrawAmountB],
1015
+ }, options?.gasLimit);
1016
+ return {
1017
+ transaction,
1018
+ result: {
1019
+ currencyA: {
1020
+ currency: pool.currencyA,
1021
+ amount: formatUnits(withdrawAmountA, pool.currencyA.decimals),
1022
+ direction: 'out',
1023
+ },
1024
+ currencyB: {
1025
+ currency: pool.currencyB,
1026
+ amount: formatUnits(withdrawAmountB, pool.currencyB.decimals),
1027
+ direction: 'out',
1028
+ },
1029
+ lpCurrency: {
1030
+ currency: pool.currencyLp,
1031
+ amount: amount,
1032
+ direction: 'in',
1033
+ },
1034
+ },
1035
+ };
1036
+ };
1037
+ export const refillOrder = async ({ chainId, userAddress, token0, token1, salt, options, }) => {
1038
+ const publicClient = createPublicClient({
1039
+ chain: CHAIN_MAP[chainId],
1040
+ transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
1041
+ });
1042
+ const pool = options?.pool
1043
+ ? options.pool
1044
+ : (await fetchPool(publicClient, chainId, [token0, token1], salt, !!(options && options.useSubgraph))).toJson();
1045
+ if (!pool.isOpened) {
1046
+ throw new Error(`
1047
+ Open the pool before rebalancing pool.
1048
+ import { openPool } from '@clober/v2-sdk'
1049
+
1050
+ const transaction = await openPool({
1051
+ chainId: ${chainId},
1052
+ tokenA: '${token0}',
1053
+ tokenB: '${token1}',
1054
+ salt: '0x0000000000000000000000000000000000000000000000000000000000000000',
1055
+ })
1056
+ `);
1057
+ }
1058
+ return buildTransaction(publicClient, {
1059
+ chain: CHAIN_MAP[chainId],
1060
+ account: userAddress,
1061
+ address: CONTRACT_ADDRESSES[chainId].Rebalancer,
1062
+ abi: REBALANCER_ABI,
1063
+ functionName: 'rebalance',
1064
+ args: [pool.key],
1065
+ }, options?.gasLimit, options?.gasPriceLimit);
1066
+ };
1067
+ export const adjustOrderPrice = async ({ chainId, userAddress, token0, token1, salt, oraclePrice, bidPrice, askPrice, alpha, options, }) => {
1068
+ if (Number(alpha) <= 0 || Number(alpha) > 1) {
1069
+ throw new Error('Alpha value must be in the range (0, 1]');
1070
+ }
1071
+ if (Number(bidPrice) <= 0 || Number(askPrice) <= 0) {
1072
+ throw new Error('Price must be greater than 0');
1073
+ }
1074
+ if (Number(bidPrice) >= Number(askPrice)) {
1075
+ throw new Error('Bid price must be less than ask price');
1076
+ }
1077
+ const publicClient = createPublicClient({
1078
+ chain: CHAIN_MAP[chainId],
1079
+ transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
1080
+ });
1081
+ const pool = options?.pool
1082
+ ? options.pool
1083
+ : (await fetchPool(publicClient, chainId, [token0, token1], salt, !!(options && options.useSubgraph))).toJson();
1084
+ if (!pool.isOpened) {
1085
+ throw new Error(`
1086
+ Open the pool before updating strategy price.
1087
+ import { openPool } from '@clober/v2-sdk'
1088
+
1089
+ const transaction = await openPool({
1090
+ chainId: ${chainId},
1091
+ tokenA: '${token0}',
1092
+ tokenB: '${token1}',
1093
+ salt: '0x0000000000000000000000000000000000000000000000000000000000000000',
1094
+ })
1095
+ `);
1096
+ }
1097
+ const [roundingUpBidPrice, roundingUpAskPrice] = [
1098
+ options?.roundingUpBidPrice ? options.roundingUpBidPrice : false,
1099
+ options?.roundingUpAskPrice ? options.roundingUpAskPrice : false,
1100
+ ];
1101
+ const { roundingDownTick: roundingDownTickA, roundingUpTick: roundingUpTickA, } = parsePrice(Number(bidPrice), pool.currencyA.decimals, pool.currencyB.decimals);
1102
+ const { roundingDownTick: roundingDownTickB, roundingUpTick: roundingUpTickB, } = parsePrice(Number(askPrice), pool.currencyA.decimals, pool.currencyB.decimals);
1103
+ const oracleRawPrice = convertHumanReadablePriceToRawPrice(Number(oraclePrice), pool.currencyA.decimals, pool.currencyB.decimals);
1104
+ const tickA = options?.bidTick
1105
+ ? Number(options.bidTick)
1106
+ : Number(roundingUpBidPrice ? roundingUpTickA : roundingDownTickA);
1107
+ let tickB = options?.askTick
1108
+ ? Number(options.askTick)
1109
+ : Number(invertTick(roundingUpAskPrice ? roundingUpTickB : roundingDownTickB));
1110
+ if (invertTick(BigInt(tickB)) <= BigInt(tickA)) {
1111
+ tickB = Number(invertTick(BigInt(tickA + 1)));
1112
+ }
1113
+ const rateRaw = parseUnits(alpha, 6);
1114
+ return buildTransaction(publicClient, {
1115
+ chain: CHAIN_MAP[chainId],
1116
+ account: userAddress,
1117
+ address: CONTRACT_ADDRESSES[chainId].Operator,
1118
+ abi: OPERATOR_ABI,
1119
+ functionName: 'updatePosition',
1120
+ args: [pool.key, oracleRawPrice, tickA, tickB, rateRaw],
1121
+ }, options?.gasLimit, options?.gasPriceLimit);
1122
+ };
1123
+ export const setStrategyConfig = async ({ chainId, userAddress, token0, token1, salt, config, options, }) => {
1124
+ // validate config
1125
+ if (Number(config.referenceThreshold) < 0 ||
1126
+ Number(config.referenceThreshold) > 1) {
1127
+ throw new Error('Reference threshold must be in the range [0, 1]');
1128
+ }
1129
+ if (Number(config.rebalanceThreshold) < 0 ||
1130
+ Number(config.rebalanceThreshold) > 1) {
1131
+ throw new Error('Rebalance threshold must be in the range [0, 1]');
1132
+ }
1133
+ if (Number(config.priceThresholdA) < 0 ||
1134
+ Number(config.priceThresholdA) > 1 ||
1135
+ Number(config.priceThresholdB) < 0 ||
1136
+ Number(config.priceThresholdB) > 1) {
1137
+ throw new Error('Price threshold must be in the range [0, 1]');
1138
+ }
1139
+ if (Number(config.rateA) < 0 ||
1140
+ Number(config.rateA) > 1 ||
1141
+ Number(config.rateB) < 0 ||
1142
+ Number(config.rateB) > 1) {
1143
+ throw new Error('Rate must be in the range [0, 1]');
1144
+ }
1145
+ if (Number(config.minRateA) < 0 ||
1146
+ Number(config.minRateA) > 1 ||
1147
+ Number(config.minRateB) < 0 ||
1148
+ Number(config.minRateB) > 1) {
1149
+ throw new Error('Min rate must be in the range [0, 1]');
1150
+ }
1151
+ if (Number(config.minRateA) > Number(config.rateA) ||
1152
+ Number(config.minRateB) > Number(config.rateB)) {
1153
+ throw new Error('Min rate must be less or equal to rate');
1154
+ }
1155
+ const publicClient = createPublicClient({
1156
+ chain: CHAIN_MAP[chainId],
1157
+ transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
1158
+ });
1159
+ const pool = await fetchPool(publicClient, chainId, [token0, token1], salt, !!(options && options.useSubgraph));
1160
+ if (!pool.isOpened) {
1161
+ throw new Error(`
1162
+ Open the pool before set strategy config.
1163
+ import { openPool } from '@clober/v2-sdk'
1164
+
1165
+ const transaction = await openPool({
1166
+ chainId: ${chainId},
1167
+ tokenA: '${token0}',
1168
+ tokenB: '${token1}',
1169
+ })
1170
+ `);
1171
+ }
1172
+ const configRaw = {
1173
+ referenceThreshold: parseUnits(config.referenceThreshold, 6),
1174
+ rebalanceThreshold: parseUnits(config.rebalanceThreshold, 6),
1175
+ rateA: parseUnits(config.rateA, 6),
1176
+ rateB: parseUnits(config.rateB, 6),
1177
+ minRateA: parseUnits(config.minRateA, 6),
1178
+ minRateB: parseUnits(config.minRateB, 6),
1179
+ priceThresholdA: parseUnits(config.priceThresholdA, 6),
1180
+ priceThresholdB: parseUnits(config.priceThresholdB, 6),
1181
+ };
1182
+ return buildTransaction(publicClient, {
1183
+ chain: CHAIN_MAP[chainId],
1184
+ account: userAddress,
1185
+ address: CONTRACT_ADDRESSES[chainId].Strategy,
1186
+ abi: STRATEGY_ABI,
1187
+ functionName: 'setConfig',
1188
+ args: [pool.key, configRaw],
1189
+ }, options?.gasLimit);
1190
+ };
1191
+ export const pausePool = async ({ chainId, userAddress, token0, token1, salt, options, }) => {
1192
+ const publicClient = createPublicClient({
1193
+ chain: CHAIN_MAP[chainId],
1194
+ transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
1195
+ });
1196
+ const pool = options?.pool
1197
+ ? options.pool
1198
+ : (await fetchPool(publicClient, chainId, [token0, token1], salt, !!(options && options.useSubgraph))).toJson();
1199
+ if (!pool.isOpened) {
1200
+ throw new Error(`
1201
+ Open the pool before trying pause.
1202
+ import { openPool } from '@clober/v2-sdk'
1203
+
1204
+ const transaction = await openPool({
1205
+ chainId: ${chainId},
1206
+ tokenA: '${token0}',
1207
+ tokenB: '${token1}',
1208
+ salt: '0x0000000000000000000000000000000000000000000000000000000000000000',
1209
+ })
1210
+ `);
1211
+ }
1212
+ if (pool.paused) {
1213
+ return undefined;
1214
+ }
1215
+ return buildTransaction(publicClient, {
1216
+ chain: CHAIN_MAP[chainId],
1217
+ account: userAddress,
1218
+ address: CONTRACT_ADDRESSES[chainId].Operator,
1219
+ abi: OPERATOR_ABI,
1220
+ functionName: 'pause',
1221
+ args: [pool.key],
1222
+ }, options?.gasLimit, options?.gasPriceLimit);
1223
+ };
1224
+ export const resumePool = async ({ chainId, userAddress, token0, token1, salt, options, }) => {
1225
+ const publicClient = createPublicClient({
1226
+ chain: CHAIN_MAP[chainId],
1227
+ transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
1228
+ });
1229
+ const pool = options?.pool
1230
+ ? options.pool
1231
+ : (await fetchPool(publicClient, chainId, [token0, token1], salt, !!(options && options.useSubgraph))).toJson();
1232
+ if (!pool.isOpened) {
1233
+ throw new Error(`
1234
+ Open the pool before trying resume.
1235
+ import { openPool } from '@clober/v2-sdk'
1236
+
1237
+ const transaction = await openPool({
1238
+ chainId: ${chainId},
1239
+ tokenA: '${token0}',
1240
+ tokenB: '${token1}',
1241
+ salt: '0x0000000000000000000000000000000000000000000000000000000000000000',
1242
+ })
1243
+ `);
1244
+ }
1245
+ if (!pool.paused) {
1246
+ return undefined;
1247
+ }
1248
+ return buildTransaction(publicClient, {
1249
+ chain: CHAIN_MAP[chainId],
1250
+ account: userAddress,
1251
+ address: CONTRACT_ADDRESSES[chainId].Strategy,
1252
+ abi: STRATEGY_ABI,
1253
+ functionName: 'unpause',
1254
+ args: [pool.key],
1255
+ }, options?.gasLimit, options?.gasPriceLimit);
1256
+ };
630
1257
  //# sourceMappingURL=call.js.map