dexbot 1.1.10

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 (807) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +287 -0
  3. package/claw/README.md +513 -0
  4. package/claw/scripts/memu_runner.py +385 -0
  5. package/claw/skills/bitshares-guide/SKILL.md +14 -0
  6. package/claw/skills/bitshares-guide/references/example-skill-shells.md +18 -0
  7. package/claw/skills/bitshares-guide/references/presentation-patterns.md +19 -0
  8. package/claw/skills/bitshares-guide/references/scope-guardrails.md +9 -0
  9. package/claw/skills/launcher-ops/SKILL.md +18 -0
  10. package/claw/skills/launcher-ops/references/launcher-workflow.md +23 -0
  11. package/claw/skills/margin-trading/SKILL.md +23 -0
  12. package/claw/skills/margin-trading/references/honest-asset-list.md +74 -0
  13. package/claw/skills/margin-trading/references/honest-assets.md +44 -0
  14. package/claw/skills/margin-trading/references/position-management.md +203 -0
  15. package/claw/skills/margin-trading/references/trading-concepts.md +80 -0
  16. package/claw/skills/memu-memory/SKILL.md +218 -0
  17. package/claw/skills/shared/references/js-automation-overview.md +24 -0
  18. package/claw/skills/shared/references/safety-and-staleness.md +11 -0
  19. package/claw/skills/shared/references/skill-boundaries.md +17 -0
  20. package/claw/skills/trend-detection/SKILL.md +33 -0
  21. package/claw/skills/trend-detection/agents/openai.yaml +3 -0
  22. package/claw/skills/trend-detection/references/service.md +45 -0
  23. package/dist/analysis/ama_fitting/analyze_ama_price_changes.d.ts +3 -0
  24. package/dist/analysis/ama_fitting/analyze_ama_price_changes.d.ts.map +1 -0
  25. package/dist/analysis/ama_fitting/analyze_ama_price_changes.js +149 -0
  26. package/dist/analysis/ama_fitting/analyze_ama_price_changes.js.map +1 -0
  27. package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.d.ts +3 -0
  28. package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.d.ts.map +1 -0
  29. package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.js +387 -0
  30. package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.js.map +1 -0
  31. package/dist/analysis/ama_fitting/calibrate_convergence_er.d.ts +3 -0
  32. package/dist/analysis/ama_fitting/calibrate_convergence_er.d.ts.map +1 -0
  33. package/dist/analysis/ama_fitting/calibrate_convergence_er.js +200 -0
  34. package/dist/analysis/ama_fitting/calibrate_convergence_er.js.map +1 -0
  35. package/dist/analysis/ama_fitting/fetch_lp_candles.d.ts +3 -0
  36. package/dist/analysis/ama_fitting/fetch_lp_candles.d.ts.map +1 -0
  37. package/dist/analysis/ama_fitting/fetch_lp_candles.js +212 -0
  38. package/dist/analysis/ama_fitting/fetch_lp_candles.js.map +1 -0
  39. package/dist/analysis/ama_fitting/generate_unified_comparison_chart.d.ts +31 -0
  40. package/dist/analysis/ama_fitting/generate_unified_comparison_chart.d.ts.map +1 -0
  41. package/dist/analysis/ama_fitting/generate_unified_comparison_chart.js +249 -0
  42. package/dist/analysis/ama_fitting/generate_unified_comparison_chart.js.map +1 -0
  43. package/dist/analysis/ama_fitting/optimizer_high_resolution.d.ts +2 -0
  44. package/dist/analysis/ama_fitting/optimizer_high_resolution.d.ts.map +1 -0
  45. package/dist/analysis/ama_fitting/optimizer_high_resolution.js +782 -0
  46. package/dist/analysis/ama_fitting/optimizer_high_resolution.js.map +1 -0
  47. package/dist/analysis/analyze_derivatives.d.ts +95 -0
  48. package/dist/analysis/analyze_derivatives.d.ts.map +1 -0
  49. package/dist/analysis/analyze_derivatives.js +295 -0
  50. package/dist/analysis/analyze_derivatives.js.map +1 -0
  51. package/dist/analysis/analyze_dynamic_weight.d.ts +14 -0
  52. package/dist/analysis/analyze_dynamic_weight.d.ts.map +1 -0
  53. package/dist/analysis/analyze_dynamic_weight.js +208 -0
  54. package/dist/analysis/analyze_dynamic_weight.js.map +1 -0
  55. package/dist/analysis/analyze_kalman.d.ts +13 -0
  56. package/dist/analysis/analyze_kalman.d.ts.map +1 -0
  57. package/dist/analysis/analyze_kalman.js +123 -0
  58. package/dist/analysis/analyze_kalman.js.map +1 -0
  59. package/dist/analysis/analyze_regime.d.ts +20 -0
  60. package/dist/analysis/analyze_regime.d.ts.map +1 -0
  61. package/dist/analysis/analyze_regime.js +139 -0
  62. package/dist/analysis/analyze_regime.js.map +1 -0
  63. package/dist/analysis/analyze_regime_windows.d.ts +19 -0
  64. package/dist/analysis/analyze_regime_windows.d.ts.map +1 -0
  65. package/dist/analysis/analyze_regime_windows.js +413 -0
  66. package/dist/analysis/analyze_regime_windows.js.map +1 -0
  67. package/dist/analysis/analyze_risk_profile.d.ts +3 -0
  68. package/dist/analysis/analyze_risk_profile.d.ts.map +1 -0
  69. package/dist/analysis/analyze_risk_profile.js +159 -0
  70. package/dist/analysis/analyze_risk_profile.js.map +1 -0
  71. package/dist/analysis/analyze_trade_heatmap.d.ts +3 -0
  72. package/dist/analysis/analyze_trade_heatmap.d.ts.map +1 -0
  73. package/dist/analysis/analyze_trade_heatmap.js +367 -0
  74. package/dist/analysis/analyze_trade_heatmap.js.map +1 -0
  75. package/dist/analysis/analyze_volatility.d.ts +22 -0
  76. package/dist/analysis/analyze_volatility.d.ts.map +1 -0
  77. package/dist/analysis/analyze_volatility.js +172 -0
  78. package/dist/analysis/analyze_volatility.js.map +1 -0
  79. package/dist/analysis/bot_fitting/backtest_ama_sweep.d.ts +99 -0
  80. package/dist/analysis/bot_fitting/backtest_ama_sweep.d.ts.map +1 -0
  81. package/dist/analysis/bot_fitting/backtest_ama_sweep.js +804 -0
  82. package/dist/analysis/bot_fitting/backtest_ama_sweep.js.map +1 -0
  83. package/dist/analysis/bot_fitting/backtest_bot_fitting.d.ts +2 -0
  84. package/dist/analysis/bot_fitting/backtest_bot_fitting.d.ts.map +1 -0
  85. package/dist/analysis/bot_fitting/backtest_bot_fitting.js +347 -0
  86. package/dist/analysis/bot_fitting/backtest_bot_fitting.js.map +1 -0
  87. package/dist/analysis/bot_fitting/shared_utils.d.ts +15 -0
  88. package/dist/analysis/bot_fitting/shared_utils.d.ts.map +1 -0
  89. package/dist/analysis/bot_fitting/shared_utils.js +48 -0
  90. package/dist/analysis/bot_fitting/shared_utils.js.map +1 -0
  91. package/dist/analysis/bot_key_utils.d.ts +16 -0
  92. package/dist/analysis/bot_key_utils.d.ts.map +1 -0
  93. package/dist/analysis/bot_key_utils.js +61 -0
  94. package/dist/analysis/bot_key_utils.js.map +1 -0
  95. package/dist/analysis/bot_usage/discover_bot_accounts.d.ts +3 -0
  96. package/dist/analysis/bot_usage/discover_bot_accounts.d.ts.map +1 -0
  97. package/dist/analysis/bot_usage/discover_bot_accounts.js +498 -0
  98. package/dist/analysis/bot_usage/discover_bot_accounts.js.map +1 -0
  99. package/dist/analysis/bot_usage/kibana_bot_queries.d.ts +546 -0
  100. package/dist/analysis/bot_usage/kibana_bot_queries.d.ts.map +1 -0
  101. package/dist/analysis/bot_usage/kibana_bot_queries.js +427 -0
  102. package/dist/analysis/bot_usage/kibana_bot_queries.js.map +1 -0
  103. package/dist/analysis/chart_utils.d.ts +13 -0
  104. package/dist/analysis/chart_utils.d.ts.map +1 -0
  105. package/dist/analysis/chart_utils.js +142 -0
  106. package/dist/analysis/chart_utils.js.map +1 -0
  107. package/dist/analysis/derivative_chart_generator.d.ts +18 -0
  108. package/dist/analysis/derivative_chart_generator.d.ts.map +1 -0
  109. package/dist/analysis/derivative_chart_generator.js +896 -0
  110. package/dist/analysis/derivative_chart_generator.js.map +1 -0
  111. package/dist/analysis/math_utils.d.ts +35 -0
  112. package/dist/analysis/math_utils.d.ts.map +1 -0
  113. package/dist/analysis/math_utils.js +121 -0
  114. package/dist/analysis/math_utils.js.map +1 -0
  115. package/dist/analysis/price_sources.d.ts +34 -0
  116. package/dist/analysis/price_sources.d.ts.map +1 -0
  117. package/dist/analysis/price_sources.js +103 -0
  118. package/dist/analysis/price_sources.js.map +1 -0
  119. package/dist/analysis/trade_profitability.d.ts +115 -0
  120. package/dist/analysis/trade_profitability.d.ts.map +1 -0
  121. package/dist/analysis/trade_profitability.js +1247 -0
  122. package/dist/analysis/trade_profitability.js.map +1 -0
  123. package/dist/analysis/tradingview/analyze_tradingview.d.ts +38 -0
  124. package/dist/analysis/tradingview/analyze_tradingview.d.ts.map +1 -0
  125. package/dist/analysis/tradingview/analyze_tradingview.js +212 -0
  126. package/dist/analysis/tradingview/analyze_tradingview.js.map +1 -0
  127. package/dist/analysis/tradingview/tradingview_uplot_chart_generator.d.ts +9 -0
  128. package/dist/analysis/tradingview/tradingview_uplot_chart_generator.d.ts.map +1 -0
  129. package/dist/analysis/tradingview/tradingview_uplot_chart_generator.js +1717 -0
  130. package/dist/analysis/tradingview/tradingview_uplot_chart_generator.js.map +1 -0
  131. package/dist/analysis/trend_detection/derivative_analyzer.d.ts +250 -0
  132. package/dist/analysis/trend_detection/derivative_analyzer.d.ts.map +1 -0
  133. package/dist/analysis/trend_detection/derivative_analyzer.js +903 -0
  134. package/dist/analysis/trend_detection/derivative_analyzer.js.map +1 -0
  135. package/dist/analysis/trend_detection/dynamic_weight_chart_generator.d.ts +6 -0
  136. package/dist/analysis/trend_detection/dynamic_weight_chart_generator.d.ts.map +1 -0
  137. package/dist/analysis/trend_detection/dynamic_weight_chart_generator.js +1449 -0
  138. package/dist/analysis/trend_detection/dynamic_weight_chart_generator.js.map +1 -0
  139. package/dist/analysis/trend_detection/hurst_analyzer.d.ts +42 -0
  140. package/dist/analysis/trend_detection/hurst_analyzer.d.ts.map +1 -0
  141. package/dist/analysis/trend_detection/hurst_analyzer.js +159 -0
  142. package/dist/analysis/trend_detection/hurst_analyzer.js.map +1 -0
  143. package/dist/analysis/trend_detection/kalman_chart_generator.d.ts +6 -0
  144. package/dist/analysis/trend_detection/kalman_chart_generator.d.ts.map +1 -0
  145. package/dist/analysis/trend_detection/kalman_chart_generator.js +408 -0
  146. package/dist/analysis/trend_detection/kalman_chart_generator.js.map +1 -0
  147. package/dist/analysis/trend_detection/kalman_trend_analyzer.d.ts +103 -0
  148. package/dist/analysis/trend_detection/kalman_trend_analyzer.d.ts.map +1 -0
  149. package/dist/analysis/trend_detection/kalman_trend_analyzer.js +229 -0
  150. package/dist/analysis/trend_detection/kalman_trend_analyzer.js.map +1 -0
  151. package/dist/analysis/trend_detection/kalman_velocity_smoothing.d.ts +34 -0
  152. package/dist/analysis/trend_detection/kalman_velocity_smoothing.d.ts.map +1 -0
  153. package/dist/analysis/trend_detection/kalman_velocity_smoothing.js +89 -0
  154. package/dist/analysis/trend_detection/kalman_velocity_smoothing.js.map +1 -0
  155. package/dist/analysis/trend_detection/permutation_entropy_analyzer.d.ts +39 -0
  156. package/dist/analysis/trend_detection/permutation_entropy_analyzer.d.ts.map +1 -0
  157. package/dist/analysis/trend_detection/permutation_entropy_analyzer.js +132 -0
  158. package/dist/analysis/trend_detection/permutation_entropy_analyzer.js.map +1 -0
  159. package/dist/analysis/trend_detection/regime_chart_generator.d.ts +6 -0
  160. package/dist/analysis/trend_detection/regime_chart_generator.d.ts.map +1 -0
  161. package/dist/analysis/trend_detection/regime_chart_generator.js +345 -0
  162. package/dist/analysis/trend_detection/regime_chart_generator.js.map +1 -0
  163. package/dist/analysis/trend_detection/tests/test_kalman_trend.d.ts +2 -0
  164. package/dist/analysis/trend_detection/tests/test_kalman_trend.d.ts.map +1 -0
  165. package/dist/analysis/trend_detection/tests/test_kalman_trend.js +130 -0
  166. package/dist/analysis/trend_detection/tests/test_kalman_trend.js.map +1 -0
  167. package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.d.ts +2 -0
  168. package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.d.ts.map +1 -0
  169. package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.js +38 -0
  170. package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.js.map +1 -0
  171. package/dist/analysis/trend_detection/volatility_chart_generator.d.ts +6 -0
  172. package/dist/analysis/trend_detection/volatility_chart_generator.d.ts.map +1 -0
  173. package/dist/analysis/trend_detection/volatility_chart_generator.js +732 -0
  174. package/dist/analysis/trend_detection/volatility_chart_generator.js.map +1 -0
  175. package/dist/bot.d.ts +49 -0
  176. package/dist/bot.d.ts.map +1 -0
  177. package/dist/bot.js +221 -0
  178. package/dist/bot.js.map +1 -0
  179. package/dist/credential-daemon.d.ts +64 -0
  180. package/dist/credential-daemon.d.ts.map +1 -0
  181. package/dist/credential-daemon.js +987 -0
  182. package/dist/credential-daemon.js.map +1 -0
  183. package/dist/dexbot.d.ts +87 -0
  184. package/dist/dexbot.d.ts.map +1 -0
  185. package/dist/dexbot.js +1222 -0
  186. package/dist/dexbot.js.map +1 -0
  187. package/dist/market_adapter/ama_signal_runner.d.ts +3 -0
  188. package/dist/market_adapter/ama_signal_runner.d.ts.map +1 -0
  189. package/dist/market_adapter/ama_signal_runner.js +175 -0
  190. package/dist/market_adapter/ama_signal_runner.js.map +1 -0
  191. package/dist/market_adapter/candle_utils.d.ts +57 -0
  192. package/dist/market_adapter/candle_utils.d.ts.map +1 -0
  193. package/dist/market_adapter/candle_utils.js +252 -0
  194. package/dist/market_adapter/candle_utils.js.map +1 -0
  195. package/dist/market_adapter/core/asymmetric_bounds.d.ts +20 -0
  196. package/dist/market_adapter/core/asymmetric_bounds.d.ts.map +1 -0
  197. package/dist/market_adapter/core/asymmetric_bounds.js +88 -0
  198. package/dist/market_adapter/core/asymmetric_bounds.js.map +1 -0
  199. package/dist/market_adapter/core/config_normalizers.d.ts +10 -0
  200. package/dist/market_adapter/core/config_normalizers.d.ts.map +1 -0
  201. package/dist/market_adapter/core/config_normalizers.js +24 -0
  202. package/dist/market_adapter/core/config_normalizers.js.map +1 -0
  203. package/dist/market_adapter/core/kibana_candles.d.ts +74 -0
  204. package/dist/market_adapter/core/kibana_candles.d.ts.map +1 -0
  205. package/dist/market_adapter/core/kibana_candles.js +249 -0
  206. package/dist/market_adapter/core/kibana_candles.js.map +1 -0
  207. package/dist/market_adapter/core/kibana_client.d.ts +27 -0
  208. package/dist/market_adapter/core/kibana_client.d.ts.map +1 -0
  209. package/dist/market_adapter/core/kibana_client.js +120 -0
  210. package/dist/market_adapter/core/kibana_client.js.map +1 -0
  211. package/dist/market_adapter/core/kibana_market_candles.d.ts +143 -0
  212. package/dist/market_adapter/core/kibana_market_candles.d.ts.map +1 -0
  213. package/dist/market_adapter/core/kibana_market_candles.js +170 -0
  214. package/dist/market_adapter/core/kibana_market_candles.js.map +1 -0
  215. package/dist/market_adapter/core/market_adapter_service.d.ts +210 -0
  216. package/dist/market_adapter/core/market_adapter_service.d.ts.map +1 -0
  217. package/dist/market_adapter/core/market_adapter_service.js +2328 -0
  218. package/dist/market_adapter/core/market_adapter_service.js.map +1 -0
  219. package/dist/market_adapter/core/strategies/ama.d.ts +2 -0
  220. package/dist/market_adapter/core/strategies/ama.d.ts.map +1 -0
  221. package/dist/market_adapter/core/strategies/ama.js +138 -0
  222. package/dist/market_adapter/core/strategies/ama.js.map +1 -0
  223. package/dist/market_adapter/core/strategies/ama_slope_model.d.ts +50 -0
  224. package/dist/market_adapter/core/strategies/ama_slope_model.d.ts.map +1 -0
  225. package/dist/market_adapter/core/strategies/ama_slope_model.js +143 -0
  226. package/dist/market_adapter/core/strategies/ama_slope_model.js.map +1 -0
  227. package/dist/market_adapter/core/strategies/atr/calculator.d.ts +12 -0
  228. package/dist/market_adapter/core/strategies/atr/calculator.d.ts.map +1 -0
  229. package/dist/market_adapter/core/strategies/atr/calculator.js +47 -0
  230. package/dist/market_adapter/core/strategies/atr/calculator.js.map +1 -0
  231. package/dist/market_adapter/core/strategies/collateral_manager.d.ts +32 -0
  232. package/dist/market_adapter/core/strategies/collateral_manager.d.ts.map +1 -0
  233. package/dist/market_adapter/core/strategies/collateral_manager.js +68 -0
  234. package/dist/market_adapter/core/strategies/collateral_manager.js.map +1 -0
  235. package/dist/market_adapter/core/strategies/regime_gate.d.ts +66 -0
  236. package/dist/market_adapter/core/strategies/regime_gate.d.ts.map +1 -0
  237. package/dist/market_adapter/core/strategies/regime_gate.js +189 -0
  238. package/dist/market_adapter/core/strategies/regime_gate.js.map +1 -0
  239. package/dist/market_adapter/index.d.ts +10 -0
  240. package/dist/market_adapter/index.d.ts.map +1 -0
  241. package/dist/market_adapter/index.js +71 -0
  242. package/dist/market_adapter/index.js.map +1 -0
  243. package/dist/market_adapter/inputs/fetch_cex_synthetic_data.d.ts +3 -0
  244. package/dist/market_adapter/inputs/fetch_cex_synthetic_data.d.ts.map +1 -0
  245. package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js +1165 -0
  246. package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js.map +1 -0
  247. package/dist/market_adapter/inputs/fetch_lp_data.d.ts +54 -0
  248. package/dist/market_adapter/inputs/fetch_lp_data.d.ts.map +1 -0
  249. package/dist/market_adapter/inputs/fetch_lp_data.js +743 -0
  250. package/dist/market_adapter/inputs/fetch_lp_data.js.map +1 -0
  251. package/dist/market_adapter/inputs/kibana_source.d.ts +68 -0
  252. package/dist/market_adapter/inputs/kibana_source.d.ts.map +1 -0
  253. package/dist/market_adapter/inputs/kibana_source.js +143 -0
  254. package/dist/market_adapter/inputs/kibana_source.js.map +1 -0
  255. package/dist/market_adapter/interval_utils.d.ts +6 -0
  256. package/dist/market_adapter/interval_utils.d.ts.map +1 -0
  257. package/dist/market_adapter/interval_utils.js +14 -0
  258. package/dist/market_adapter/interval_utils.js.map +1 -0
  259. package/dist/market_adapter/log_format.d.ts +16 -0
  260. package/dist/market_adapter/log_format.d.ts.map +1 -0
  261. package/dist/market_adapter/log_format.js +72 -0
  262. package/dist/market_adapter/log_format.js.map +1 -0
  263. package/dist/market_adapter/lp_chart_core.d.ts +6 -0
  264. package/dist/market_adapter/lp_chart_core.d.ts.map +1 -0
  265. package/dist/market_adapter/lp_chart_core.js +874 -0
  266. package/dist/market_adapter/lp_chart_core.js.map +1 -0
  267. package/dist/market_adapter/lp_chart_runner.d.ts +135 -0
  268. package/dist/market_adapter/lp_chart_runner.d.ts.map +1 -0
  269. package/dist/market_adapter/lp_chart_runner.js +337 -0
  270. package/dist/market_adapter/lp_chart_runner.js.map +1 -0
  271. package/dist/market_adapter/lp_chart_strategy_loader.d.ts +23 -0
  272. package/dist/market_adapter/lp_chart_strategy_loader.d.ts.map +1 -0
  273. package/dist/market_adapter/lp_chart_strategy_loader.js +169 -0
  274. package/dist/market_adapter/lp_chart_strategy_loader.js.map +1 -0
  275. package/dist/market_adapter/market_adapter.d.ts +133 -0
  276. package/dist/market_adapter/market_adapter.d.ts.map +1 -0
  277. package/dist/market_adapter/market_adapter.js +1331 -0
  278. package/dist/market_adapter/market_adapter.js.map +1 -0
  279. package/dist/market_adapter/merge_lp_data.d.ts +3 -0
  280. package/dist/market_adapter/merge_lp_data.d.ts.map +1 -0
  281. package/dist/market_adapter/merge_lp_data.js +125 -0
  282. package/dist/market_adapter/merge_lp_data.js.map +1 -0
  283. package/dist/market_adapter/test_helpers.d.ts +14 -0
  284. package/dist/market_adapter/test_helpers.d.ts.map +1 -0
  285. package/dist/market_adapter/test_helpers.js +22 -0
  286. package/dist/market_adapter/test_helpers.js.map +1 -0
  287. package/dist/market_adapter/utils/adapter_client.d.ts +20 -0
  288. package/dist/market_adapter/utils/adapter_client.d.ts.map +1 -0
  289. package/dist/market_adapter/utils/adapter_client.js +88 -0
  290. package/dist/market_adapter/utils/adapter_client.js.map +1 -0
  291. package/dist/market_adapter/utils/atomic_write.d.ts +9 -0
  292. package/dist/market_adapter/utils/atomic_write.d.ts.map +1 -0
  293. package/dist/market_adapter/utils/atomic_write.js +13 -0
  294. package/dist/market_adapter/utils/atomic_write.js.map +1 -0
  295. package/dist/market_adapter/utils/chain.d.ts +50 -0
  296. package/dist/market_adapter/utils/chain.d.ts.map +1 -0
  297. package/dist/market_adapter/utils/chain.js +196 -0
  298. package/dist/market_adapter/utils/chain.js.map +1 -0
  299. package/dist/market_adapter/utils/data_discovery.d.ts +6 -0
  300. package/dist/market_adapter/utils/data_discovery.d.ts.map +1 -0
  301. package/dist/market_adapter/utils/data_discovery.js +35 -0
  302. package/dist/market_adapter/utils/data_discovery.js.map +1 -0
  303. package/dist/market_adapter/utils/dynamic_grid_snapshot.d.ts +15 -0
  304. package/dist/market_adapter/utils/dynamic_grid_snapshot.d.ts.map +1 -0
  305. package/dist/market_adapter/utils/dynamic_grid_snapshot.js +60 -0
  306. package/dist/market_adapter/utils/dynamic_grid_snapshot.js.map +1 -0
  307. package/dist/market_adapter/utils/file_lock.d.ts +19 -0
  308. package/dist/market_adapter/utils/file_lock.d.ts.map +1 -0
  309. package/dist/market_adapter/utils/file_lock.js +191 -0
  310. package/dist/market_adapter/utils/file_lock.js.map +1 -0
  311. package/dist/market_adapter/utils/native_history.d.ts +19 -0
  312. package/dist/market_adapter/utils/native_history.d.ts.map +1 -0
  313. package/dist/market_adapter/utils/native_history.js +172 -0
  314. package/dist/market_adapter/utils/native_history.js.map +1 -0
  315. package/dist/market_adapter/utils/paths.d.ts +5 -0
  316. package/dist/market_adapter/utils/paths.d.ts.map +1 -0
  317. package/dist/market_adapter/utils/paths.js +7 -0
  318. package/dist/market_adapter/utils/paths.js.map +1 -0
  319. package/dist/modules/account_bots.d.ts +112 -0
  320. package/dist/modules/account_bots.d.ts.map +1 -0
  321. package/dist/modules/account_bots.js +1259 -0
  322. package/dist/modules/account_bots.js.map +1 -0
  323. package/dist/modules/account_orders.d.ts +273 -0
  324. package/dist/modules/account_orders.d.ts.map +1 -0
  325. package/dist/modules/account_orders.js +662 -0
  326. package/dist/modules/account_orders.js.map +1 -0
  327. package/dist/modules/authority_resolver.d.ts +2 -0
  328. package/dist/modules/authority_resolver.d.ts.map +1 -0
  329. package/dist/modules/authority_resolver.js +231 -0
  330. package/dist/modules/authority_resolver.js.map +1 -0
  331. package/dist/modules/bitshares-native/chain_client.d.ts +38 -0
  332. package/dist/modules/bitshares-native/chain_client.d.ts.map +1 -0
  333. package/dist/modules/bitshares-native/chain_client.js +322 -0
  334. package/dist/modules/bitshares-native/chain_client.js.map +1 -0
  335. package/dist/modules/bitshares-native/crypto/ecc.browser.d.ts +59 -0
  336. package/dist/modules/bitshares-native/crypto/ecc.browser.d.ts.map +1 -0
  337. package/dist/modules/bitshares-native/crypto/ecc.browser.js +456 -0
  338. package/dist/modules/bitshares-native/crypto/ecc.browser.js.map +1 -0
  339. package/dist/modules/bitshares-native/crypto/ecc.d.ts +66 -0
  340. package/dist/modules/bitshares-native/crypto/ecc.d.ts.map +1 -0
  341. package/dist/modules/bitshares-native/crypto/ecc.js +557 -0
  342. package/dist/modules/bitshares-native/crypto/ecc.js.map +1 -0
  343. package/dist/modules/bitshares-native/crypto/ecc_selector.d.ts +2 -0
  344. package/dist/modules/bitshares-native/crypto/ecc_selector.d.ts.map +1 -0
  345. package/dist/modules/bitshares-native/crypto/ecc_selector.js +20 -0
  346. package/dist/modules/bitshares-native/crypto/ecc_selector.js.map +1 -0
  347. package/dist/modules/bitshares-native/index.d.ts +3 -0
  348. package/dist/modules/bitshares-native/index.d.ts.map +1 -0
  349. package/dist/modules/bitshares-native/index.js +32 -0
  350. package/dist/modules/bitshares-native/index.js.map +1 -0
  351. package/dist/modules/bitshares-native/resolvers.d.ts +40 -0
  352. package/dist/modules/bitshares-native/resolvers.d.ts.map +1 -0
  353. package/dist/modules/bitshares-native/resolvers.js +161 -0
  354. package/dist/modules/bitshares-native/resolvers.js.map +1 -0
  355. package/dist/modules/bitshares-native/serial/chain_constants.d.ts +56 -0
  356. package/dist/modules/bitshares-native/serial/chain_constants.d.ts.map +1 -0
  357. package/dist/modules/bitshares-native/serial/chain_constants.js +92 -0
  358. package/dist/modules/bitshares-native/serial/chain_constants.js.map +1 -0
  359. package/dist/modules/bitshares-native/serial/index.d.ts +10 -0
  360. package/dist/modules/bitshares-native/serial/index.d.ts.map +1 -0
  361. package/dist/modules/bitshares-native/serial/index.js +14 -0
  362. package/dist/modules/bitshares-native/serial/index.js.map +1 -0
  363. package/dist/modules/bitshares-native/serial/operations.d.ts +102 -0
  364. package/dist/modules/bitshares-native/serial/operations.d.ts.map +1 -0
  365. package/dist/modules/bitshares-native/serial/operations.js +615 -0
  366. package/dist/modules/bitshares-native/serial/operations.js.map +1 -0
  367. package/dist/modules/bitshares-native/serial/serializer.d.ts +64 -0
  368. package/dist/modules/bitshares-native/serial/serializer.d.ts.map +1 -0
  369. package/dist/modules/bitshares-native/serial/serializer.js +252 -0
  370. package/dist/modules/bitshares-native/serial/serializer.js.map +1 -0
  371. package/dist/modules/bitshares-native/serial/types.d.ts +120 -0
  372. package/dist/modules/bitshares-native/serial/types.d.ts.map +1 -0
  373. package/dist/modules/bitshares-native/serial/types.js +837 -0
  374. package/dist/modules/bitshares-native/serial/types.js.map +1 -0
  375. package/dist/modules/bitshares-native/signing_client.d.ts +6 -0
  376. package/dist/modules/bitshares-native/signing_client.d.ts.map +1 -0
  377. package/dist/modules/bitshares-native/signing_client.js +141 -0
  378. package/dist/modules/bitshares-native/signing_client.js.map +1 -0
  379. package/dist/modules/bitshares-native/subscriptions.d.ts +6 -0
  380. package/dist/modules/bitshares-native/subscriptions.d.ts.map +1 -0
  381. package/dist/modules/bitshares-native/subscriptions.js +865 -0
  382. package/dist/modules/bitshares-native/subscriptions.js.map +1 -0
  383. package/dist/modules/bitshares-native/transport.d.ts +51 -0
  384. package/dist/modules/bitshares-native/transport.d.ts.map +1 -0
  385. package/dist/modules/bitshares-native/transport.js +447 -0
  386. package/dist/modules/bitshares-native/transport.js.map +1 -0
  387. package/dist/modules/bitshares-native/tx/builder.d.ts +30 -0
  388. package/dist/modules/bitshares-native/tx/builder.d.ts.map +1 -0
  389. package/dist/modules/bitshares-native/tx/builder.js +262 -0
  390. package/dist/modules/bitshares-native/tx/builder.js.map +1 -0
  391. package/dist/modules/bitshares_client.d.ts +129 -0
  392. package/dist/modules/bitshares_client.d.ts.map +1 -0
  393. package/dist/modules/bitshares_client.js +627 -0
  394. package/dist/modules/bitshares_client.js.map +1 -0
  395. package/dist/modules/bot_settings.d.ts +33 -0
  396. package/dist/modules/bot_settings.d.ts.map +1 -0
  397. package/dist/modules/bot_settings.js +328 -0
  398. package/dist/modules/bot_settings.js.map +1 -0
  399. package/dist/modules/bots_file_lock.d.ts +88 -0
  400. package/dist/modules/bots_file_lock.d.ts.map +1 -0
  401. package/dist/modules/bots_file_lock.js +161 -0
  402. package/dist/modules/bots_file_lock.js.map +1 -0
  403. package/dist/modules/chain_keys.d.ts +302 -0
  404. package/dist/modules/chain_keys.d.ts.map +1 -0
  405. package/dist/modules/chain_keys.js +1095 -0
  406. package/dist/modules/chain_keys.js.map +1 -0
  407. package/dist/modules/chain_orders.d.ts +423 -0
  408. package/dist/modules/chain_orders.d.ts.map +1 -0
  409. package/dist/modules/chain_orders.js +1201 -0
  410. package/dist/modules/chain_orders.js.map +1 -0
  411. package/dist/modules/cli_whitelist_args.d.ts +6 -0
  412. package/dist/modules/cli_whitelist_args.d.ts.map +1 -0
  413. package/dist/modules/cli_whitelist_args.js +13 -0
  414. package/dist/modules/cli_whitelist_args.js.map +1 -0
  415. package/dist/modules/config.d.ts +57 -0
  416. package/dist/modules/config.d.ts.map +1 -0
  417. package/dist/modules/config.js +107 -0
  418. package/dist/modules/config.js.map +1 -0
  419. package/dist/modules/constants.d.ts +635 -0
  420. package/dist/modules/constants.d.ts.map +1 -0
  421. package/dist/modules/constants.js +1464 -0
  422. package/dist/modules/constants.js.map +1 -0
  423. package/dist/modules/cr_planner.d.ts +51 -0
  424. package/dist/modules/cr_planner.d.ts.map +1 -0
  425. package/dist/modules/cr_planner.js +299 -0
  426. package/dist/modules/cr_planner.js.map +1 -0
  427. package/dist/modules/credential_policy.d.ts +188 -0
  428. package/dist/modules/credential_policy.d.ts.map +1 -0
  429. package/dist/modules/credential_policy.js +1452 -0
  430. package/dist/modules/credential_policy.js.map +1 -0
  431. package/dist/modules/credential_runtime.d.ts +42 -0
  432. package/dist/modules/credential_runtime.d.ts.map +1 -0
  433. package/dist/modules/credential_runtime.js +148 -0
  434. package/dist/modules/credential_runtime.js.map +1 -0
  435. package/dist/modules/credential_session_cache.d.ts +36 -0
  436. package/dist/modules/credential_session_cache.d.ts.map +1 -0
  437. package/dist/modules/credential_session_cache.js +106 -0
  438. package/dist/modules/credential_session_cache.js.map +1 -0
  439. package/dist/modules/credit_runtime.d.ts +412 -0
  440. package/dist/modules/credit_runtime.d.ts.map +1 -0
  441. package/dist/modules/credit_runtime.js +2866 -0
  442. package/dist/modules/credit_runtime.js.map +1 -0
  443. package/dist/modules/crypto/browser_provider.d.ts +15 -0
  444. package/dist/modules/crypto/browser_provider.d.ts.map +1 -0
  445. package/dist/modules/crypto/browser_provider.js +113 -0
  446. package/dist/modules/crypto/browser_provider.js.map +1 -0
  447. package/dist/modules/crypto/index.d.ts +9 -0
  448. package/dist/modules/crypto/index.d.ts.map +1 -0
  449. package/dist/modules/crypto/index.js +44 -0
  450. package/dist/modules/crypto/index.js.map +1 -0
  451. package/dist/modules/crypto/node_provider.d.ts +15 -0
  452. package/dist/modules/crypto/node_provider.d.ts.map +1 -0
  453. package/dist/modules/crypto/node_provider.js +74 -0
  454. package/dist/modules/crypto/node_provider.js.map +1 -0
  455. package/dist/modules/crypto/provider.d.ts +34 -0
  456. package/dist/modules/crypto/provider.d.ts.map +1 -0
  457. package/dist/modules/crypto/provider.js +3 -0
  458. package/dist/modules/crypto/provider.js.map +1 -0
  459. package/dist/modules/crypto/pure_ripemd160.d.ts +8 -0
  460. package/dist/modules/crypto/pure_ripemd160.d.ts.map +1 -0
  461. package/dist/modules/crypto/pure_ripemd160.js +142 -0
  462. package/dist/modules/crypto/pure_ripemd160.js.map +1 -0
  463. package/dist/modules/crypto/pure_scrypt.d.ts +23 -0
  464. package/dist/modules/crypto/pure_scrypt.d.ts.map +1 -0
  465. package/dist/modules/crypto/pure_scrypt.js +161 -0
  466. package/dist/modules/crypto/pure_scrypt.js.map +1 -0
  467. package/dist/modules/crypto/pure_secp256k1.d.ts +29 -0
  468. package/dist/modules/crypto/pure_secp256k1.d.ts.map +1 -0
  469. package/dist/modules/crypto/pure_secp256k1.js +195 -0
  470. package/dist/modules/crypto/pure_secp256k1.js.map +1 -0
  471. package/dist/modules/crypto/sync.d.ts +13 -0
  472. package/dist/modules/crypto/sync.d.ts.map +1 -0
  473. package/dist/modules/crypto/sync.js +37 -0
  474. package/dist/modules/crypto/sync.js.map +1 -0
  475. package/dist/modules/dexbot_class.d.ts +1074 -0
  476. package/dist/modules/dexbot_class.d.ts.map +1 -0
  477. package/dist/modules/dexbot_class.js +4613 -0
  478. package/dist/modules/dexbot_class.js.map +1 -0
  479. package/dist/modules/dexbot_credential_client.d.ts +71 -0
  480. package/dist/modules/dexbot_credential_client.d.ts.map +1 -0
  481. package/dist/modules/dexbot_credential_client.js +224 -0
  482. package/dist/modules/dexbot_credential_client.js.map +1 -0
  483. package/dist/modules/dexbot_fill_runtime.d.ts +173 -0
  484. package/dist/modules/dexbot_fill_runtime.d.ts.map +1 -0
  485. package/dist/modules/dexbot_fill_runtime.js +217 -0
  486. package/dist/modules/dexbot_fill_runtime.js.map +1 -0
  487. package/dist/modules/dexbot_maintenance_runtime.d.ts +279 -0
  488. package/dist/modules/dexbot_maintenance_runtime.d.ts.map +1 -0
  489. package/dist/modules/dexbot_maintenance_runtime.js +1613 -0
  490. package/dist/modules/dexbot_maintenance_runtime.js.map +1 -0
  491. package/dist/modules/env.d.ts +12 -0
  492. package/dist/modules/env.d.ts.map +1 -0
  493. package/dist/modules/env.js +57 -0
  494. package/dist/modules/env.js.map +1 -0
  495. package/dist/modules/fund_registry.d.ts +96 -0
  496. package/dist/modules/fund_registry.d.ts.map +1 -0
  497. package/dist/modules/fund_registry.js +261 -0
  498. package/dist/modules/fund_registry.js.map +1 -0
  499. package/dist/modules/general_settings.d.ts +36 -0
  500. package/dist/modules/general_settings.d.ts.map +1 -0
  501. package/dist/modules/general_settings.js +63 -0
  502. package/dist/modules/general_settings.js.map +1 -0
  503. package/dist/modules/graceful_shutdown.d.ts +86 -0
  504. package/dist/modules/graceful_shutdown.d.ts.map +1 -0
  505. package/dist/modules/graceful_shutdown.js +164 -0
  506. package/dist/modules/graceful_shutdown.js.map +1 -0
  507. package/dist/modules/key_store.d.ts +60 -0
  508. package/dist/modules/key_store.d.ts.map +1 -0
  509. package/dist/modules/key_store.js +215 -0
  510. package/dist/modules/key_store.js.map +1 -0
  511. package/dist/modules/launcher/bot_supervisor.d.ts +84 -0
  512. package/dist/modules/launcher/bot_supervisor.d.ts.map +1 -0
  513. package/dist/modules/launcher/bot_supervisor.js +1067 -0
  514. package/dist/modules/launcher/bot_supervisor.js.map +1 -0
  515. package/dist/modules/launcher/child_env.d.ts +9 -0
  516. package/dist/modules/launcher/child_env.d.ts.map +1 -0
  517. package/dist/modules/launcher/child_env.js +78 -0
  518. package/dist/modules/launcher/child_env.js.map +1 -0
  519. package/dist/modules/launcher/credential_bootstrap.d.ts +22 -0
  520. package/dist/modules/launcher/credential_bootstrap.d.ts.map +1 -0
  521. package/dist/modules/launcher/credential_bootstrap.js +303 -0
  522. package/dist/modules/launcher/credential_bootstrap.js.map +1 -0
  523. package/dist/modules/launcher/credential_daemon.d.ts +32 -0
  524. package/dist/modules/launcher/credential_daemon.d.ts.map +1 -0
  525. package/dist/modules/launcher/credential_daemon.js +173 -0
  526. package/dist/modules/launcher/credential_daemon.js.map +1 -0
  527. package/dist/modules/launcher/credential_secret.d.ts +6 -0
  528. package/dist/modules/launcher/credential_secret.d.ts.map +1 -0
  529. package/dist/modules/launcher/credential_secret.js +15 -0
  530. package/dist/modules/launcher/credential_secret.js.map +1 -0
  531. package/dist/modules/launcher/foreign_cred_daemon.d.ts +2 -0
  532. package/dist/modules/launcher/foreign_cred_daemon.d.ts.map +1 -0
  533. package/dist/modules/launcher/foreign_cred_daemon.js +166 -0
  534. package/dist/modules/launcher/foreign_cred_daemon.js.map +1 -0
  535. package/dist/modules/launcher/headless_password.d.ts +8 -0
  536. package/dist/modules/launcher/headless_password.d.ts.map +1 -0
  537. package/dist/modules/launcher/headless_password.js +33 -0
  538. package/dist/modules/launcher/headless_password.js.map +1 -0
  539. package/dist/modules/launcher/launch_modes.d.ts +36 -0
  540. package/dist/modules/launcher/launch_modes.d.ts.map +1 -0
  541. package/dist/modules/launcher/launch_modes.js +129 -0
  542. package/dist/modules/launcher/launch_modes.js.map +1 -0
  543. package/dist/modules/launcher/market_adapter_runtime.d.ts +43 -0
  544. package/dist/modules/launcher/market_adapter_runtime.d.ts.map +1 -0
  545. package/dist/modules/launcher/market_adapter_runtime.js +217 -0
  546. package/dist/modules/launcher/market_adapter_runtime.js.map +1 -0
  547. package/dist/modules/launcher/market_adapter_watchdog.d.ts +26 -0
  548. package/dist/modules/launcher/market_adapter_watchdog.d.ts.map +1 -0
  549. package/dist/modules/launcher/market_adapter_watchdog.js +214 -0
  550. package/dist/modules/launcher/market_adapter_watchdog.js.map +1 -0
  551. package/dist/modules/launcher/monolithic_runtime.d.ts +89 -0
  552. package/dist/modules/launcher/monolithic_runtime.d.ts.map +1 -0
  553. package/dist/modules/launcher/monolithic_runtime.js +425 -0
  554. package/dist/modules/launcher/monolithic_runtime.js.map +1 -0
  555. package/dist/modules/launcher/runtime_entry.d.ts +26 -0
  556. package/dist/modules/launcher/runtime_entry.d.ts.map +1 -0
  557. package/dist/modules/launcher/runtime_entry.js +49 -0
  558. package/dist/modules/launcher/runtime_entry.js.map +1 -0
  559. package/dist/modules/launcher/status_reporting.d.ts +48 -0
  560. package/dist/modules/launcher/status_reporting.d.ts.map +1 -0
  561. package/dist/modules/launcher/status_reporting.js +113 -0
  562. package/dist/modules/launcher/status_reporting.js.map +1 -0
  563. package/dist/modules/launcher/supervisor_control.d.ts +6 -0
  564. package/dist/modules/launcher/supervisor_control.d.ts.map +1 -0
  565. package/dist/modules/launcher/supervisor_control.js +59 -0
  566. package/dist/modules/launcher/supervisor_control.js.map +1 -0
  567. package/dist/modules/logger.d.ts +2 -0
  568. package/dist/modules/logger.d.ts.map +1 -0
  569. package/dist/modules/logger.js +71 -0
  570. package/dist/modules/logger.js.map +1 -0
  571. package/dist/modules/market_adapter_whitelist.d.ts +22 -0
  572. package/dist/modules/market_adapter_whitelist.d.ts.map +1 -0
  573. package/dist/modules/market_adapter_whitelist.js +82 -0
  574. package/dist/modules/market_adapter_whitelist.js.map +1 -0
  575. package/dist/modules/node_health_cache.d.ts +55 -0
  576. package/dist/modules/node_health_cache.d.ts.map +1 -0
  577. package/dist/modules/node_health_cache.js +134 -0
  578. package/dist/modules/node_health_cache.js.map +1 -0
  579. package/dist/modules/node_manager.d.ts +215 -0
  580. package/dist/modules/node_manager.d.ts.map +1 -0
  581. package/dist/modules/node_manager.js +628 -0
  582. package/dist/modules/node_manager.js.map +1 -0
  583. package/dist/modules/order/accounting.d.ts +349 -0
  584. package/dist/modules/order/accounting.d.ts.map +1 -0
  585. package/dist/modules/order/accounting.js +1191 -0
  586. package/dist/modules/order/accounting.js.map +1 -0
  587. package/dist/modules/order/async_lock.d.ts +126 -0
  588. package/dist/modules/order/async_lock.d.ts.map +1 -0
  589. package/dist/modules/order/async_lock.js +195 -0
  590. package/dist/modules/order/async_lock.js.map +1 -0
  591. package/dist/modules/order/export.d.ts +129 -0
  592. package/dist/modules/order/export.d.ts.map +1 -0
  593. package/dist/modules/order/export.js +316 -0
  594. package/dist/modules/order/export.js.map +1 -0
  595. package/dist/modules/order/format.d.ts +158 -0
  596. package/dist/modules/order/format.d.ts.map +1 -0
  597. package/dist/modules/order/format.js +232 -0
  598. package/dist/modules/order/format.js.map +1 -0
  599. package/dist/modules/order/grid.d.ts +549 -0
  600. package/dist/modules/order/grid.d.ts.map +1 -0
  601. package/dist/modules/order/grid.js +1746 -0
  602. package/dist/modules/order/grid.js.map +1 -0
  603. package/dist/modules/order/grid_reconcile.d.ts +154 -0
  604. package/dist/modules/order/grid_reconcile.d.ts.map +1 -0
  605. package/dist/modules/order/grid_reconcile.js +1192 -0
  606. package/dist/modules/order/grid_reconcile.js.map +1 -0
  607. package/dist/modules/order/index.d.ts +55 -0
  608. package/dist/modules/order/index.d.ts.map +1 -0
  609. package/dist/modules/order/index.js +79 -0
  610. package/dist/modules/order/index.js.map +1 -0
  611. package/dist/modules/order/logger.d.ts +136 -0
  612. package/dist/modules/order/logger.d.ts.map +1 -0
  613. package/dist/modules/order/logger.js +614 -0
  614. package/dist/modules/order/logger.js.map +1 -0
  615. package/dist/modules/order/logger_state.d.ts +133 -0
  616. package/dist/modules/order/logger_state.d.ts.map +1 -0
  617. package/dist/modules/order/logger_state.js +170 -0
  618. package/dist/modules/order/logger_state.js.map +1 -0
  619. package/dist/modules/order/manager.d.ts +413 -0
  620. package/dist/modules/order/manager.d.ts.map +1 -0
  621. package/dist/modules/order/manager.js +1605 -0
  622. package/dist/modules/order/manager.js.map +1 -0
  623. package/dist/modules/order/processed_fill_store.d.ts +135 -0
  624. package/dist/modules/order/processed_fill_store.d.ts.map +1 -0
  625. package/dist/modules/order/processed_fill_store.js +288 -0
  626. package/dist/modules/order/processed_fill_store.js.map +1 -0
  627. package/dist/modules/order/runner.d.ts +70 -0
  628. package/dist/modules/order/runner.d.ts.map +1 -0
  629. package/dist/modules/order/runner.js +140 -0
  630. package/dist/modules/order/runner.js.map +1 -0
  631. package/dist/modules/order/strategy.d.ts +196 -0
  632. package/dist/modules/order/strategy.d.ts.map +1 -0
  633. package/dist/modules/order/strategy.js +398 -0
  634. package/dist/modules/order/strategy.js.map +1 -0
  635. package/dist/modules/order/sync_engine.d.ts +386 -0
  636. package/dist/modules/order/sync_engine.d.ts.map +1 -0
  637. package/dist/modules/order/sync_engine.js +1459 -0
  638. package/dist/modules/order/sync_engine.js.map +1 -0
  639. package/dist/modules/order/utils/math.d.ts +677 -0
  640. package/dist/modules/order/utils/math.d.ts.map +1 -0
  641. package/dist/modules/order/utils/math.js +1172 -0
  642. package/dist/modules/order/utils/math.js.map +1 -0
  643. package/dist/modules/order/utils/order.d.ts +572 -0
  644. package/dist/modules/order/utils/order.d.ts.map +1 -0
  645. package/dist/modules/order/utils/order.js +1145 -0
  646. package/dist/modules/order/utils/order.js.map +1 -0
  647. package/dist/modules/order/utils/system.d.ts +268 -0
  648. package/dist/modules/order/utils/system.d.ts.map +1 -0
  649. package/dist/modules/order/utils/system.js +1261 -0
  650. package/dist/modules/order/utils/system.js.map +1 -0
  651. package/dist/modules/order/utils/validate.d.ts +280 -0
  652. package/dist/modules/order/utils/validate.d.ts.map +1 -0
  653. package/dist/modules/order/utils/validate.js +918 -0
  654. package/dist/modules/order/utils/validate.js.map +1 -0
  655. package/dist/modules/order/working_grid.d.ts +212 -0
  656. package/dist/modules/order/working_grid.d.ts.map +1 -0
  657. package/dist/modules/order/working_grid.js +279 -0
  658. package/dist/modules/order/working_grid.js.map +1 -0
  659. package/dist/modules/path_api.d.ts +32 -0
  660. package/dist/modules/path_api.d.ts.map +1 -0
  661. package/dist/modules/path_api.js +148 -0
  662. package/dist/modules/path_api.js.map +1 -0
  663. package/dist/modules/paths.d.ts +58 -0
  664. package/dist/modules/paths.d.ts.map +1 -0
  665. package/dist/modules/paths.js +82 -0
  666. package/dist/modules/paths.js.map +1 -0
  667. package/dist/modules/process_discovery.d.ts +58 -0
  668. package/dist/modules/process_discovery.d.ts.map +1 -0
  669. package/dist/modules/process_discovery.js +265 -0
  670. package/dist/modules/process_discovery.js.map +1 -0
  671. package/dist/modules/runtime.d.ts +34 -0
  672. package/dist/modules/runtime.d.ts.map +1 -0
  673. package/dist/modules/runtime.js +98 -0
  674. package/dist/modules/runtime.js.map +1 -0
  675. package/dist/modules/runtime_settings.d.ts +12 -0
  676. package/dist/modules/runtime_settings.d.ts.map +1 -0
  677. package/dist/modules/runtime_settings.js +122 -0
  678. package/dist/modules/runtime_settings.js.map +1 -0
  679. package/dist/modules/settings_merge.d.ts +38 -0
  680. package/dist/modules/settings_merge.d.ts.map +1 -0
  681. package/dist/modules/settings_merge.js +246 -0
  682. package/dist/modules/settings_merge.js.map +1 -0
  683. package/dist/modules/storage/browser_adapter.d.ts +56 -0
  684. package/dist/modules/storage/browser_adapter.d.ts.map +1 -0
  685. package/dist/modules/storage/browser_adapter.js +231 -0
  686. package/dist/modules/storage/browser_adapter.js.map +1 -0
  687. package/dist/modules/storage/index.d.ts +28 -0
  688. package/dist/modules/storage/index.d.ts.map +1 -0
  689. package/dist/modules/storage/index.js +52 -0
  690. package/dist/modules/storage/index.js.map +1 -0
  691. package/dist/modules/storage/node_adapter.d.ts +49 -0
  692. package/dist/modules/storage/node_adapter.d.ts.map +1 -0
  693. package/dist/modules/storage/node_adapter.js +167 -0
  694. package/dist/modules/storage/node_adapter.js.map +1 -0
  695. package/dist/modules/storage/types.d.ts +92 -0
  696. package/dist/modules/storage/types.d.ts.map +1 -0
  697. package/dist/modules/storage/types.js +3 -0
  698. package/dist/modules/storage/types.js.map +1 -0
  699. package/dist/modules/types.d.ts +1382 -0
  700. package/dist/modules/types.d.ts.map +1 -0
  701. package/dist/modules/types.js +11 -0
  702. package/dist/modules/types.js.map +1 -0
  703. package/dist/modules/utils/base58check.d.ts +12 -0
  704. package/dist/modules/utils/base58check.d.ts.map +1 -0
  705. package/dist/modules/utils/base58check.js +112 -0
  706. package/dist/modules/utils/base58check.js.map +1 -0
  707. package/dist/modules/utils/build_dir.d.ts +7 -0
  708. package/dist/modules/utils/build_dir.d.ts.map +1 -0
  709. package/dist/modules/utils/build_dir.js +8 -0
  710. package/dist/modules/utils/build_dir.js.map +1 -0
  711. package/dist/modules/utils/fs_utils.d.ts +25 -0
  712. package/dist/modules/utils/fs_utils.d.ts.map +1 -0
  713. package/dist/modules/utils/fs_utils.js +27 -0
  714. package/dist/modules/utils/fs_utils.js.map +1 -0
  715. package/dist/modules/utils/math_utils.d.ts +10 -0
  716. package/dist/modules/utils/math_utils.d.ts.map +1 -0
  717. package/dist/modules/utils/math_utils.js +17 -0
  718. package/dist/modules/utils/math_utils.js.map +1 -0
  719. package/dist/modules/validate_profiles.d.ts +37 -0
  720. package/dist/modules/validate_profiles.d.ts.map +1 -0
  721. package/dist/modules/validate_profiles.js +369 -0
  722. package/dist/modules/validate_profiles.js.map +1 -0
  723. package/dist/pm2.d.ts +167 -0
  724. package/dist/pm2.d.ts.map +1 -0
  725. package/dist/pm2.js +998 -0
  726. package/dist/pm2.js.map +1 -0
  727. package/dist/scripts/analyze-git.d.ts +11 -0
  728. package/dist/scripts/analyze-git.d.ts.map +1 -0
  729. package/dist/scripts/analyze-git.js +851 -0
  730. package/dist/scripts/analyze-git.js.map +1 -0
  731. package/dist/scripts/analyze-orders.d.ts +17 -0
  732. package/dist/scripts/analyze-orders.d.ts.map +1 -0
  733. package/dist/scripts/analyze-orders.js +1568 -0
  734. package/dist/scripts/analyze-orders.js.map +1 -0
  735. package/dist/scripts/diagnose-kibana-candles.d.ts +3 -0
  736. package/dist/scripts/diagnose-kibana-candles.d.ts.map +1 -0
  737. package/dist/scripts/diagnose-kibana-candles.js +82 -0
  738. package/dist/scripts/diagnose-kibana-candles.js.map +1 -0
  739. package/dist/scripts/diagnose-pool-history.d.ts +3 -0
  740. package/dist/scripts/diagnose-pool-history.d.ts.map +1 -0
  741. package/dist/scripts/diagnose-pool-history.js +296 -0
  742. package/dist/scripts/diagnose-pool-history.js.map +1 -0
  743. package/dist/scripts/divergence-calc.d.ts +26 -0
  744. package/dist/scripts/divergence-calc.d.ts.map +1 -0
  745. package/dist/scripts/divergence-calc.js +119 -0
  746. package/dist/scripts/divergence-calc.js.map +1 -0
  747. package/dist/scripts/generate_lp_chart.d.ts +31 -0
  748. package/dist/scripts/generate_lp_chart.d.ts.map +1 -0
  749. package/dist/scripts/generate_lp_chart.js +92 -0
  750. package/dist/scripts/generate_lp_chart.js.map +1 -0
  751. package/dist/scripts/generate_mainnet_corpus_report.d.ts +24 -0
  752. package/dist/scripts/generate_mainnet_corpus_report.d.ts.map +1 -0
  753. package/dist/scripts/generate_mainnet_corpus_report.js +237 -0
  754. package/dist/scripts/generate_mainnet_corpus_report.js.map +1 -0
  755. package/dist/scripts/generate_market_adapter_whitelist.d.ts +2 -0
  756. package/dist/scripts/generate_market_adapter_whitelist.d.ts.map +1 -0
  757. package/dist/scripts/generate_market_adapter_whitelist.js +111 -0
  758. package/dist/scripts/generate_market_adapter_whitelist.js.map +1 -0
  759. package/dist/scripts/migrate_bot_keys.d.ts +6 -0
  760. package/dist/scripts/migrate_bot_keys.d.ts.map +1 -0
  761. package/dist/scripts/migrate_bot_keys.js +301 -0
  762. package/dist/scripts/migrate_bot_keys.js.map +1 -0
  763. package/dist/scripts/native_release_gates.d.ts +3 -0
  764. package/dist/scripts/native_release_gates.d.ts.map +1 -0
  765. package/dist/scripts/native_release_gates.js +52 -0
  766. package/dist/scripts/native_release_gates.js.map +1 -0
  767. package/dist/scripts/print_grid.d.ts +16 -0
  768. package/dist/scripts/print_grid.d.ts.map +1 -0
  769. package/dist/scripts/print_grid.js +80 -0
  770. package/dist/scripts/print_grid.js.map +1 -0
  771. package/dist/scripts/run-tests.d.ts +2 -0
  772. package/dist/scripts/run-tests.d.ts.map +1 -0
  773. package/dist/scripts/run-tests.js +49 -0
  774. package/dist/scripts/run-tests.js.map +1 -0
  775. package/dist/scripts/sync-version.d.ts +14 -0
  776. package/dist/scripts/sync-version.d.ts.map +1 -0
  777. package/dist/scripts/sync-version.js +158 -0
  778. package/dist/scripts/sync-version.js.map +1 -0
  779. package/dist/scripts/test-credit-renewal.d.ts +2 -0
  780. package/dist/scripts/test-credit-renewal.d.ts.map +1 -0
  781. package/dist/scripts/test-credit-renewal.js +329 -0
  782. package/dist/scripts/test-credit-renewal.js.map +1 -0
  783. package/dist/scripts/update.d.ts +24 -0
  784. package/dist/scripts/update.d.ts.map +1 -0
  785. package/dist/scripts/update.js +650 -0
  786. package/dist/scripts/update.js.map +1 -0
  787. package/dist/scripts/validate_bots.d.ts +16 -0
  788. package/dist/scripts/validate_bots.d.ts.map +1 -0
  789. package/dist/scripts/validate_bots.js +106 -0
  790. package/dist/scripts/validate_bots.js.map +1 -0
  791. package/dist/scripts/verify-browser-bundle.d.ts +22 -0
  792. package/dist/scripts/verify-browser-bundle.d.ts.map +1 -0
  793. package/dist/scripts/verify-browser-bundle.js +339 -0
  794. package/dist/scripts/verify-browser-bundle.js.map +1 -0
  795. package/dist/unlock.d.ts +48 -0
  796. package/dist/unlock.d.ts.map +1 -0
  797. package/dist/unlock.js +925 -0
  798. package/dist/unlock.js.map +1 -0
  799. package/package.json +112 -0
  800. package/scripts/README.md +356 -0
  801. package/scripts/clear-all.sh +195 -0
  802. package/scripts/clear-logs.sh +95 -0
  803. package/scripts/clear-market-adapter.sh +196 -0
  804. package/scripts/clear-orders.sh +113 -0
  805. package/scripts/create-bot-symlinks.sh +51 -0
  806. package/scripts/postinstall.js +9 -0
  807. package/scripts/reset-settings.sh +118 -0
@@ -0,0 +1,1605 @@
1
+ "use strict";
2
+ /**
3
+ * modules/order/manager.ts - OrderManager Engine
4
+ *
5
+ * Core grid-based order management system for DEXBot2.
6
+ * Uses utils/validate.ts, strategy.ts, and utils/order.ts for validation and rebalance logic.
7
+ *
8
+ * ===============================================================================
9
+ * TABLE OF CONTENTS
10
+ * ===============================================================================
11
+ *
12
+ * SECTION 1: EXTERNAL DEPENDENCIES
13
+ * SECTION 2: COW REBALANCE ENGINE
14
+ * SECTION 3: STATE MANAGER
15
+ * SECTION 4: ORDER MANAGER CLASS
16
+ * ===============================================================================
17
+ */
18
+ // ===============================================================================
19
+ // SECTION 1: EXTERNAL DEPENDENCIES
20
+ // ===============================================================================
21
+ const { ORDER_TYPES, ORDER_STATES, REBALANCE_STATES, COW_ACTIONS, DEFAULT_CONFIG, TIMING, LOG_LEVEL, PIPELINE_TIMING, COW_PERFORMANCE } = require('../constants');
22
+ const { getMinAbsoluteOrderSize, computeChainFundTotals, hasValidAccountTotals, resolveConfigValue, resolveConfigValueWithRegistry, isExplicitZeroAllocation, floatToBlockchainInt, getPrecisionSlack } = require('./utils/math');
23
+ const { isOrderOnChain, isPhantomOrder, hasOnChainId, convertToSpreadPlaceholder } = require('./utils/order');
24
+ const { persistGridSnapshot, deepFreeze, cloneMap } = require('./utils/system');
25
+ const { validateOrder, validateGridForPersistence, calculateRequiredFunds, validateWorkingGridFunds, checkFundDrift, reconcileGrid, optimizeRebalanceActions, summarizeActions, projectTargetToWorkingGrid, buildStateUpdates, buildAbortedResult, buildSuccessResult, evaluateCommit } = require('./utils/validate');
26
+ const { WorkingGrid } = require('./working_grid');
27
+ const Logger = require('./logger');
28
+ const AsyncLock = require('./async_lock');
29
+ const Accountant = require('./accounting');
30
+ const StrategyEngine = require('./strategy');
31
+ const SyncEngine = require('./sync_engine');
32
+ const Grid = require('./grid');
33
+ const Format = require('./format');
34
+ const { toFiniteNumber, isValidNumber } = Format;
35
+ // ===============================================================================
36
+ // SECTION 2: COW REBALANCE ENGINE
37
+ // ===============================================================================
38
+ //
39
+ // COPY-ON-WRITE (COW) PATTERN FOR SAFE REBALANCING
40
+ //
41
+ // Problem Solved:
42
+ // Traditional approach: Modify orders in-place while calculating new grid
43
+ // Issue: If fills arrive DURING rebalance, they corrupt the working state
44
+ //
45
+ // Solution: Copy-on-Write pattern isolates rebalancing from incoming fills
46
+ //
47
+ // WORKFLOW:
48
+ // 1. Clone master grid → WorkingGrid (immutable during rebalance)
49
+ // 2. Calculate target state from strategy engine
50
+ // 3. Reconcile master vs target → generate COW_ACTIONS (CREATE/UPDATE/CANCEL/ROTATE)
51
+ // 4. Project target to working grid (working becomes target)
52
+ // 5. Validate funds and check for staleness (abort if fills arrived)
53
+ // 6. Build blockchain operations from delta
54
+ // 7. Atomic commit to master on broadcast success (or discard on failure)
55
+ //
56
+ // KEY INVARIANTS:
57
+ // 1. Master grid NEVER modified during planning (immutable during rebalance)
58
+ // 2. Fills that arrive during rebalance are QUEUED, not lost
59
+ // 3. Working grid is DISPOSABLE - if rebalance fails, discard it
60
+ // 4. Only ONE rebalance plan active at a time (StateManager.rebalance)
61
+ // 5. Staleness detection aborts if master changes (fills, manual commands)
62
+ //
63
+ // FILL HANDLING DURING REBALANCE:
64
+ // - SyncEngine.syncFromFillHistory() is called immediately on fill arrival
65
+ // - Updates to master grid only (not working grid)
66
+ // - Sets workingGrid.markStale() to signal version mismatch
67
+ // - Rebalance detects staleness → aborts → retries on next cycle
68
+ // - Fills are NEVER lost, just deferred until next rebalance cycle
69
+ //
70
+ // PERFORMANCE OPTIMIZATION:
71
+ // - COW_PERFORMANCE.WORKING_GRID_BYTES_PER_ORDER estimated memory per order
72
+ // - Modified Set only tracks changed order IDs (delta compression)
73
+ // - Lazy index calculation (prices, types, states) only on demand
74
+ // - Delta building is O(n) where n = modified orders count
75
+ //
76
+ // ===============================================================================
77
+ class COWRebalanceEngine {
78
+ strategy;
79
+ logger;
80
+ assets;
81
+ config;
82
+ constructor(deps) {
83
+ this.strategy = deps.strategy;
84
+ this.logger = deps.logger;
85
+ this.assets = deps.assets;
86
+ this.config = deps.config;
87
+ }
88
+ async execute({ masterGrid, gridVersion, boundaryIdx, funds, fills = [], excludeIds = new Set() }) {
89
+ const startTime = Date.now();
90
+ const workingGrid = new WorkingGrid(masterGrid, { baseVersion: gridVersion });
91
+ const strategyParams = {
92
+ frozenMasterGrid: masterGrid,
93
+ config: this.config,
94
+ accountAssets: this.assets,
95
+ funds,
96
+ excludeIds,
97
+ fills,
98
+ currentBoundaryIdx: boundaryIdx
99
+ };
100
+ const { targetGrid, boundaryIdx: targetBoundary } = this.strategy.calculateTargetGrid(strategyParams);
101
+ let dustThresholdPercent = this.config?.gridLimits?.PARTIAL_DUST_THRESHOLD_PERCENTAGE;
102
+ const reconcileResult = reconcileGrid(masterGrid, targetGrid, targetBoundary, {
103
+ logger: (msg, level) => this.logger?.log(msg, level),
104
+ dustThresholdPercent
105
+ });
106
+ if (reconcileResult.aborted) {
107
+ return buildAbortedResult(reconcileResult.reason);
108
+ }
109
+ const optimizedActions = optimizeRebalanceActions(reconcileResult.actions, masterGrid);
110
+ projectTargetToWorkingGrid(workingGrid, targetGrid, { actions: optimizedActions });
111
+ const precisions = {
112
+ buyPrecision: this.assets?.assetB?.precision,
113
+ sellPrecision: this.assets?.assetA?.precision
114
+ };
115
+ const fundCheck = validateWorkingGridFunds(workingGrid, funds, precisions, this.assets);
116
+ if (!fundCheck.isValid) {
117
+ this.logger?.log(`[COW] Fund validation failed: ${fundCheck.reason}`, 'warn');
118
+ return buildAbortedResult(fundCheck.reason);
119
+ }
120
+ if (workingGrid.isStale()) {
121
+ const reason = workingGrid.getStaleReason() || 'Master grid changed during planning';
122
+ this.logger?.log(`[COW] Rebalance plan invalidated: ${reason}`, 'warn');
123
+ return buildAbortedResult(reason);
124
+ }
125
+ const stateUpdates = buildStateUpdates(optimizedActions, masterGrid);
126
+ const duration = Date.now() - startTime;
127
+ if (duration > 100) {
128
+ this.logger?.log(`[COW] Rebalance planning took ${duration}ms`, 'warn');
129
+ }
130
+ this.logger?.log(`[COW] Plan: Actions=${optimizedActions.length}, StateUpdates=${stateUpdates.length}`, 'info');
131
+ return buildSuccessResult({
132
+ actions: optimizedActions,
133
+ stateUpdates,
134
+ workingGrid,
135
+ workingBoundary: targetBoundary,
136
+ planningDuration: duration
137
+ });
138
+ }
139
+ }
140
+ // ===============================================================================
141
+ // SECTION 3: STATE MANAGER
142
+ // ===============================================================================
143
+ class StateManager {
144
+ logger;
145
+ rebalance;
146
+ recovery;
147
+ gridRegen;
148
+ bootstrap;
149
+ broadcast;
150
+ signals;
151
+ pipeline;
152
+ constructor(options = {}) {
153
+ this.logger = options.logger || null;
154
+ this.reset();
155
+ }
156
+ reset() {
157
+ this.rebalance = {
158
+ state: REBALANCE_STATES.NORMAL,
159
+ currentWorkingGrid: null
160
+ };
161
+ this.recovery = {
162
+ attemptCount: 0,
163
+ lastAttemptAt: 0,
164
+ inFlight: false,
165
+ lastFailureAt: 0
166
+ };
167
+ this.gridRegen = {
168
+ buy: { armed: true, lastTriggeredAt: 0 },
169
+ sell: { armed: true, lastTriggeredAt: 0 }
170
+ };
171
+ this.bootstrap = {
172
+ isBootstrapping: false
173
+ };
174
+ this.broadcast = {
175
+ isBroadcasting: false,
176
+ startedAt: 0,
177
+ };
178
+ this.signals = {
179
+ lastIllegalState: null,
180
+ lastAccountingFailure: null
181
+ };
182
+ this.pipeline = {
183
+ blockedSince: null,
184
+ recoveryAttempted: false
185
+ };
186
+ }
187
+ getRebalanceState() {
188
+ return this.rebalance.state;
189
+ }
190
+ setRebalanceState(state) {
191
+ this.rebalance.state = state;
192
+ this.logger?.log(`[COW] Rebalance state: ${state}`, 'debug');
193
+ }
194
+ isRebalancing() {
195
+ return this.rebalance.state === REBALANCE_STATES.REBALANCING;
196
+ }
197
+ isBroadcasting() {
198
+ return this.rebalance.state === REBALANCE_STATES.BROADCASTING;
199
+ }
200
+ setWorkingGrid(workingGrid) {
201
+ this.rebalance.currentWorkingGrid = workingGrid;
202
+ }
203
+ getWorkingGrid() {
204
+ return this.rebalance.currentWorkingGrid;
205
+ }
206
+ clearWorkingGrid() {
207
+ this.rebalance.currentWorkingGrid = null;
208
+ }
209
+ recordRecoveryAttempt() {
210
+ this.recovery.attemptCount++;
211
+ this.recovery.lastAttemptAt = Date.now();
212
+ this.recovery.inFlight = true;
213
+ }
214
+ completeRecovery(success) {
215
+ this.recovery.inFlight = false;
216
+ if (!success) {
217
+ this.recovery.lastFailureAt = Date.now();
218
+ }
219
+ }
220
+ isRecoveryInFlight() {
221
+ return this.recovery.inFlight;
222
+ }
223
+ getRecoveryStats() {
224
+ return { ...this.recovery };
225
+ }
226
+ isSideArmed(side) {
227
+ return this.gridRegen[side]?.armed ?? false;
228
+ }
229
+ disarmSide(side) {
230
+ if (this.gridRegen[side]) {
231
+ this.gridRegen[side].armed = false;
232
+ this.gridRegen[side].lastTriggeredAt = Date.now();
233
+ }
234
+ }
235
+ armSide(side) {
236
+ if (this.gridRegen[side]) {
237
+ this.gridRegen[side].armed = true;
238
+ }
239
+ }
240
+ startBootstrap() {
241
+ this.bootstrap.isBootstrapping = true;
242
+ this.logger?.log('[BOOTSTRAP] Started', 'debug');
243
+ }
244
+ finishBootstrap() {
245
+ this.bootstrap.isBootstrapping = false;
246
+ this.logger?.log('[BOOTSTRAP] Finished', 'debug');
247
+ }
248
+ isBootstrapping() {
249
+ return this.bootstrap.isBootstrapping;
250
+ }
251
+ startBroadcasting() {
252
+ this.broadcast.isBroadcasting = true;
253
+ this.broadcast.startedAt = Date.now();
254
+ this.logger?.log?.('[BROADCAST] Flag set — fill processing will be deferred until stopBroadcasting()', 'debug');
255
+ }
256
+ stopBroadcasting() {
257
+ this.broadcast.isBroadcasting = false;
258
+ this.broadcast.startedAt = 0;
259
+ }
260
+ isBroadcastingActive() {
261
+ if (this.broadcast.isBroadcasting && this.broadcast.startedAt > 0) {
262
+ const elapsed = Date.now() - this.broadcast.startedAt;
263
+ if (elapsed > 120000) {
264
+ this.logger?.log?.('[BROADCAST] Auto-clearing stale broadcast flag after 120s', 'warn');
265
+ this.broadcast.isBroadcasting = false;
266
+ this.broadcast.startedAt = 0;
267
+ }
268
+ }
269
+ return this.broadcast.isBroadcasting;
270
+ }
271
+ setIllegalStateSignal(signal) {
272
+ this.signals.lastIllegalState = {
273
+ ...signal,
274
+ at: Date.now()
275
+ };
276
+ }
277
+ consumeIllegalStateSignal() {
278
+ const signal = this.signals.lastIllegalState;
279
+ this.signals.lastIllegalState = null;
280
+ return signal;
281
+ }
282
+ setAccountingFailureSignal(signal) {
283
+ this.signals.lastAccountingFailure = {
284
+ ...signal,
285
+ at: Date.now()
286
+ };
287
+ }
288
+ consumeAccountingFailureSignal() {
289
+ const signal = this.signals.lastAccountingFailure;
290
+ this.signals.lastAccountingFailure = null;
291
+ return signal;
292
+ }
293
+ markPipelineBlocked() {
294
+ if (!this.pipeline.blockedSince) {
295
+ this.pipeline.blockedSince = Date.now();
296
+ }
297
+ }
298
+ markPipelineClear() {
299
+ this.pipeline.blockedSince = null;
300
+ this.pipeline.recoveryAttempted = false;
301
+ }
302
+ getPipelineBlockedDuration() {
303
+ return this.pipeline.blockedSince ? Date.now() - this.pipeline.blockedSince : 0;
304
+ }
305
+ isPipelineBlocked() {
306
+ return this.pipeline.blockedSince !== null;
307
+ }
308
+ getState() {
309
+ return {
310
+ rebalance: { ...this.rebalance, currentWorkingGrid: null },
311
+ recovery: { ...this.recovery },
312
+ gridRegen: { ...this.gridRegen },
313
+ bootstrap: { ...this.bootstrap },
314
+ broadcast: { ...this.broadcast },
315
+ pipeline: { ...this.pipeline }
316
+ };
317
+ }
318
+ }
319
+ // ===============================================================================
320
+ // SECTION 4: ORDER MANAGER CLASS
321
+ // ===============================================================================
322
+ class OrderManager {
323
+ config;
324
+ marketName;
325
+ logger;
326
+ orders;
327
+ boundaryIdx;
328
+ targetGrid;
329
+ accountant;
330
+ strategy;
331
+ sync;
332
+ _state;
333
+ _ordersByState;
334
+ _ordersByType;
335
+ targetSpreadCount;
336
+ currentSpreadCount;
337
+ outOfSpread;
338
+ assets;
339
+ accountId;
340
+ accountTotals;
341
+ funds;
342
+ _accountTotalsPromise;
343
+ _accountTotalsResolve;
344
+ _isFetchingTotals;
345
+ ordersNeedingPriceCorrection;
346
+ shadowOrderIds;
347
+ processedFillTracker;
348
+ processedFillStore;
349
+ _syncLock;
350
+ _fillProcessingLock;
351
+ _divergenceLock;
352
+ _gridLock;
353
+ _fundLock;
354
+ _recentlyRotatedOrderIds;
355
+ _gridSidesUpdated;
356
+ _pauseFundRecalc;
357
+ _pauseRecalcLogging;
358
+ _throwOnIllegalState;
359
+ _pipelineBlockedSince;
360
+ _recoveryAttempted;
361
+ _gridVersion;
362
+ _gridPersistenceSuspendedReason;
363
+ _pendingBroadcasts;
364
+ _gridDirty;
365
+ _gridDirtyReasons;
366
+ _gridDirtySince;
367
+ _metrics;
368
+ _currentWorkingGrid;
369
+ _cowEngine;
370
+ accountOrders;
371
+ btsBalance;
372
+ /**
373
+ * @param {Object} [config] - Configuration overrides
374
+ */
375
+ constructor(config = {}) {
376
+ this.config = { ...DEFAULT_CONFIG, ...config };
377
+ this.marketName = this.config.market || (this.config.assetA && this.config.assetB ? `${this.config.assetA}/${this.config.assetB}` : null);
378
+ const logFile = config.logFile || undefined;
379
+ const loggingConfig = this.config.logging;
380
+ this.logger = new Logger('DEXBot', {
381
+ level: loggingConfig?.level ?? LOG_LEVEL,
382
+ logFile,
383
+ configOverride: loggingConfig?.config ?? undefined
384
+ });
385
+ this.logger.marketName = this.marketName;
386
+ this.orders = Object.freeze(new Map());
387
+ this.boundaryIdx = null;
388
+ this.targetGrid = null;
389
+ this.accountant = new Accountant(this);
390
+ this.strategy = new StrategyEngine(this);
391
+ this.sync = new SyncEngine(this);
392
+ this._state = new StateManager({ logger: this.logger });
393
+ // Index Sets use mutable mutation patterns controlled via _applyOrderUpdate
394
+ // These are private implementation details and must NOT be mutated directly
395
+ // All external code must go through the COW pipeline
396
+ this._ordersByState = {
397
+ [ORDER_STATES.VIRTUAL]: new Set(),
398
+ [ORDER_STATES.ACTIVE]: new Set(),
399
+ [ORDER_STATES.PARTIAL]: new Set()
400
+ };
401
+ this._ordersByType = {
402
+ [ORDER_TYPES.BUY]: new Set(),
403
+ [ORDER_TYPES.SELL]: new Set(),
404
+ [ORDER_TYPES.SPREAD]: new Set()
405
+ };
406
+ this.resetFunds();
407
+ this.btsBalance = { free: 0, total: 0, locked: 0 };
408
+ this.targetSpreadCount = 0;
409
+ this.currentSpreadCount = 0;
410
+ this.outOfSpread = 0;
411
+ this.assets = null;
412
+ this._accountTotalsPromise = null;
413
+ this._accountTotalsResolve = null;
414
+ this._isFetchingTotals = false;
415
+ this.ordersNeedingPriceCorrection = [];
416
+ this.shadowOrderIds = new Map();
417
+ this.processedFillTracker = new Map();
418
+ this.processedFillStore = null;
419
+ // LOCK HIERARCHY (convention — not enforced at runtime to avoid false
420
+ // positives from async contention and multi-bot sharing a process).
421
+ // Acquire in ascending level order only:
422
+ // Level 0: _divergenceLock (divergence checks — outermost)
423
+ // Level 1: _fillProcessingLock (fill processing)
424
+ // Level 2: _gridLock (grid mutations)
425
+ // Level 3: _syncLock (sync operations)
426
+ // Level 4: _fundLock (fund operations — innermost)
427
+ // WARNING: AsyncLock is NOT reentrant.
428
+ this._divergenceLock = new AsyncLock({ level: 0 });
429
+ this._fillProcessingLock = new AsyncLock({ level: 1 });
430
+ this._gridLock = new AsyncLock({ level: 2 });
431
+ this._syncLock = new AsyncLock({ level: 3 });
432
+ this._fundLock = new AsyncLock({ level: 4, timeout: 30000 });
433
+ this._recentlyRotatedOrderIds = new Set();
434
+ this._gridSidesUpdated = new Set();
435
+ this._pauseFundRecalc = 0;
436
+ this._pauseRecalcLogging = false;
437
+ this._throwOnIllegalState = false;
438
+ this._pipelineBlockedSince = null;
439
+ this._recoveryAttempted = false;
440
+ this._gridVersion = 0;
441
+ this._gridPersistenceSuspendedReason = null;
442
+ this._pendingBroadcasts = new Map();
443
+ this._gridDirty = false;
444
+ this._gridDirtyReasons = new Map();
445
+ this._gridDirtySince = null;
446
+ this._metrics = {
447
+ fundRecalcCount: 0,
448
+ invariantViolations: { buy: 0, sell: 0 },
449
+ lockAcquisitions: 0,
450
+ lockContentionSkips: 0,
451
+ spreadRoleConversionBlocked: 0,
452
+ lastSyncDurationMs: 0,
453
+ metricsStartTime: Date.now()
454
+ };
455
+ this._state.startBootstrap();
456
+ this._currentWorkingGrid = null;
457
+ this._cowEngine = null;
458
+ this._cleanExpiredLocks();
459
+ }
460
+ _getCOWEngine() {
461
+ if (!this._cowEngine && this.assets) {
462
+ this._cowEngine = new COWRebalanceEngine({
463
+ strategy: this.strategy,
464
+ logger: this.logger,
465
+ assets: this.assets,
466
+ config: this.config
467
+ });
468
+ }
469
+ return this._cowEngine;
470
+ }
471
+ _clearWorkingGridRef() {
472
+ this._currentWorkingGrid = null;
473
+ this._state.clearWorkingGrid();
474
+ this._state.setRebalanceState(REBALANCE_STATES.NORMAL);
475
+ }
476
+ _setRebalanceState(state) {
477
+ this._state.setRebalanceState(state);
478
+ }
479
+ /**
480
+ * @returns {boolean}
481
+ */
482
+ isRebalancing() {
483
+ return this._state.isRebalancing();
484
+ }
485
+ /**
486
+ * @returns {boolean}
487
+ */
488
+ isBroadcasting() {
489
+ return this._state.isBroadcasting();
490
+ }
491
+ /**
492
+ * @returns {boolean}
493
+ */
494
+ isPlanningActive() {
495
+ return this.isRebalancing() || this.isBroadcasting();
496
+ }
497
+ /**
498
+ * @returns {void}
499
+ */
500
+ startBootstrap() {
501
+ this._state.startBootstrap();
502
+ }
503
+ /**
504
+ * @returns {import('./types').BootstrapResult}
505
+ */
506
+ finishBootstrap() {
507
+ const result = { hadDrift: false, driftInfo: null };
508
+ if (this._state.isBootstrapping()) {
509
+ this._state.finishBootstrap();
510
+ // Validate fund state at bootstrap completion - if drift exists here,
511
+ // it's not transient (grid is now stable) and indicates a potential bug
512
+ const driftCheck = this.checkFundDriftAfterFills();
513
+ if (!driftCheck.isValid) {
514
+ result.hadDrift = true;
515
+ result.driftInfo = driftCheck;
516
+ this.logger.log(`[BOOTSTRAP-END] Fund drift detected after bootstrap: ${driftCheck.reason}. ` +
517
+ `This may indicate a bug in grid initialization.`, 'warn');
518
+ }
519
+ this.logger.log("Bootstrap phase complete. Grid health monitoring and fund invariants active.", "info");
520
+ }
521
+ return result;
522
+ }
523
+ /**
524
+ * @returns {void}
525
+ */
526
+ startBroadcasting() {
527
+ this._state.startBroadcasting();
528
+ }
529
+ /**
530
+ * @returns {void}
531
+ */
532
+ stopBroadcasting() {
533
+ this._state.stopBroadcasting();
534
+ }
535
+ /**
536
+ * @returns {void}
537
+ */
538
+ resetFunds() {
539
+ return this.accountant.resetFunds();
540
+ }
541
+ async _deductFromChainFree(orderType, size, operation) {
542
+ if (!this.accountant)
543
+ return;
544
+ return await this.accountant.tryDeductFromChainFree(orderType, size, operation);
545
+ }
546
+ async _addToChainFree(orderType, size, operation) {
547
+ if (!this.accountant)
548
+ return;
549
+ return await this.accountant.addToChainFree(orderType, size, operation);
550
+ }
551
+ _getGridTotal(side) {
552
+ return (this.funds?.committed?.grid?.[side] || 0) + (this.funds?.virtual?.[side] || 0);
553
+ }
554
+ /**
555
+ * @returns {import('./types').ChainFundsSnapshot}
556
+ */
557
+ getChainFundsSnapshot() {
558
+ const totals = computeChainFundTotals(this.accountTotals, this.funds?.committed?.chain);
559
+ const allocatedBuy = toFiniteNumber(this.funds?.allocated?.buy, totals.chainTotalBuy);
560
+ const allocatedSell = toFiniteNumber(this.funds?.allocated?.sell, totals.chainTotalSell);
561
+ const btsBalance = (this.config.assetA !== 'BTS' && this.config.assetB !== 'BTS')
562
+ ? (this.btsBalance || { free: 0, total: 0, locked: 0 })
563
+ : null;
564
+ return { ...totals, allocatedBuy, allocatedSell, btsBalance };
565
+ }
566
+ /**
567
+ * @param {number} [timeoutMs]
568
+ * @returns {Promise<void>}
569
+ */
570
+ async waitForAccountTotals(timeoutMs = TIMING.ACCOUNT_TOTALS_TIMEOUT_MS) {
571
+ if (hasValidAccountTotals(this.accountTotals, true))
572
+ return;
573
+ let waitPromise = null;
574
+ await this._fundLock.acquire(async () => {
575
+ if (hasValidAccountTotals(this.accountTotals, true))
576
+ return;
577
+ if (!this._accountTotalsPromise) {
578
+ this._accountTotalsPromise = new Promise((resolve) => {
579
+ this._accountTotalsResolve = resolve;
580
+ });
581
+ }
582
+ waitPromise = this._accountTotalsPromise;
583
+ });
584
+ if (!waitPromise)
585
+ return;
586
+ await Promise.race([
587
+ waitPromise,
588
+ new Promise((resolve) => {
589
+ setTimeout(() => {
590
+ this.logger.log('[FUND] Timeout waiting for account totals', 'warn');
591
+ resolve();
592
+ }, timeoutMs);
593
+ })
594
+ ]);
595
+ }
596
+ /**
597
+ * @param {string} [accountId] - Blockchain account ID
598
+ * @returns {Promise<void>}
599
+ */
600
+ async fetchAccountTotals(accountId) {
601
+ if (accountId)
602
+ this.accountId = accountId;
603
+ await this._fetchAccountBalancesAndSetTotals();
604
+ }
605
+ async _fetchAccountBalancesAndSetTotals() {
606
+ return await this.sync.fetchAccountBalancesAndSetTotals();
607
+ }
608
+ /**
609
+ * @param {import('./types').AccountTotals} totals - Account balance totals
610
+ * @returns {Promise<void>}
611
+ */
612
+ async setAccountTotals(totals = { buy: null, sell: null, buyFree: null, sellFree: null }) {
613
+ return await this._fundLock.acquire(async () => {
614
+ return await this._setAccountTotals(totals);
615
+ });
616
+ }
617
+ async _setAccountTotals(totals) {
618
+ this.accountTotals = { ...(this.accountTotals || {}), ...totals };
619
+ if (!this.funds)
620
+ this.resetFunds();
621
+ await this._recalculateFunds();
622
+ if (hasValidAccountTotals(this.accountTotals, true) && typeof this._accountTotalsResolve === 'function') {
623
+ try {
624
+ this._accountTotalsResolve();
625
+ }
626
+ catch (e) {
627
+ this.logger?.log?.(`Error resolving account totals promise: ${e.message}`, 'warn');
628
+ }
629
+ this._accountTotalsPromise = null;
630
+ this._accountTotalsResolve = null;
631
+ }
632
+ }
633
+ _triggerAccountTotalsFetchIfNeeded() {
634
+ if (!this._isFetchingTotals) {
635
+ this._isFetchingTotals = true;
636
+ this._fetchAccountBalancesAndSetTotals().finally(() => {
637
+ this._isFetchingTotals = false;
638
+ });
639
+ }
640
+ }
641
+ /**
642
+ * @returns {void}
643
+ */
644
+ applyBotFundsAllocation() {
645
+ if (!this.config.botFunds || !this.accountTotals)
646
+ return;
647
+ const { chainTotalBuy, chainTotalSell } = computeChainFundTotals(this.accountTotals, this.funds?.committed?.chain);
648
+ const account = this.config.preferredAccount;
649
+ const botName = this.config.botKey;
650
+ const allocatedBuy = resolveConfigValueWithRegistry(this.config.botFunds.buy, chainTotalBuy, account, botName, 'buy');
651
+ const allocatedSell = resolveConfigValueWithRegistry(this.config.botFunds.sell, chainTotalSell, account, botName, 'sell');
652
+ if (allocatedBuy === 0 && typeof this.config.botFunds.buy === 'string' && this.config.botFunds.buy.trim().endsWith('%')) {
653
+ if (chainTotalBuy === 0)
654
+ this._triggerAccountTotalsFetchIfNeeded();
655
+ }
656
+ if (allocatedSell === 0 && typeof this.config.botFunds.sell === 'string' && this.config.botFunds.sell.trim().endsWith('%')) {
657
+ if (chainTotalSell === 0)
658
+ this._triggerAccountTotalsFetchIfNeeded();
659
+ }
660
+ this.funds.allocated = { buy: allocatedBuy, sell: allocatedSell };
661
+ const shouldCapBuy = allocatedBuy > 0 || isExplicitZeroAllocation(this.config.botFunds.buy);
662
+ const shouldCapSell = allocatedSell > 0 || isExplicitZeroAllocation(this.config.botFunds.sell);
663
+ if (shouldCapBuy)
664
+ this.funds.available.buy = Math.min(this.funds.available.buy, Math.max(0, allocatedBuy));
665
+ if (shouldCapSell)
666
+ this.funds.available.sell = Math.min(this.funds.available.sell, Math.max(0, allocatedSell));
667
+ }
668
+ /**
669
+ * @returns {Promise<void>}
670
+ */
671
+ async recalculateFunds() {
672
+ return await this._fundLock.acquire(async () => {
673
+ return await this._recalculateFunds();
674
+ });
675
+ }
676
+ async _recalculateFunds() {
677
+ if (!this.accountant)
678
+ return;
679
+ this._metrics.fundRecalcCount++;
680
+ await this.accountant.recalculateFunds();
681
+ }
682
+ /**
683
+ * @returns {void}
684
+ */
685
+ pauseFundRecalc() {
686
+ this._pauseFundRecalc++;
687
+ }
688
+ /**
689
+ * @returns {Promise<void>}
690
+ */
691
+ async resumeFundRecalc() {
692
+ this._pauseFundRecalc = Math.max(0, this._pauseFundRecalc - 1);
693
+ if (this._pauseFundRecalc === 0) {
694
+ await this.recalculateFunds();
695
+ }
696
+ }
697
+ /**
698
+ * @returns {void}
699
+ */
700
+ pauseRecalcLogging() {
701
+ this._pauseRecalcLogging = true;
702
+ }
703
+ /**
704
+ * @returns {void}
705
+ */
706
+ resumeRecalcLogging() {
707
+ this._pauseRecalcLogging = false;
708
+ }
709
+ /**
710
+ * @param {Array<import('./types').Order>} orders
711
+ * @param {Object} info
712
+ * @returns {Promise<import('./types').SyncResult>}
713
+ */
714
+ syncFromOpenOrders(orders, info) {
715
+ return this.sync.syncFromOpenOrders(orders, info);
716
+ }
717
+ /**
718
+ * @param {Object} fill - Fill event data
719
+ * @param {Object} [options]
720
+ * @returns {Promise<import('./types').SyncResult>}
721
+ */
722
+ syncFromFillHistory(fill, options) {
723
+ return this.sync.syncFromFillHistory(fill, options);
724
+ }
725
+ /**
726
+ * @param {Object} data - Chain data to synchronize
727
+ * @param {string} src - Source identifier
728
+ * @returns {Promise<import('./types').SyncResult>}
729
+ */
730
+ async synchronizeWithChain(data, src, options = {}) {
731
+ // _gridLock acquisition is delegated to sync.synchronizeWithChain itself.
732
+ // createOrder / cancelOrder acquire it inline; readOpenOrders and
733
+ // periodicBlockchainFetch acquire it inside syncFromOpenOrders.
734
+ return await this._applySync(data, src, options);
735
+ }
736
+ async _applySync(data, src, options = {}) {
737
+ return await this.sync.synchronizeWithChain(data, src, options);
738
+ }
739
+ async _initializeAssets() {
740
+ return await this.sync.initializeAssets();
741
+ }
742
+ /**
743
+ * @param {string[]|Set<string>} orderIds - Order IDs to lock
744
+ * @returns {void}
745
+ */
746
+ lockOrders(orderIds) {
747
+ if (!orderIds)
748
+ return;
749
+ const expiration = Date.now() + TIMING.LOCK_TIMEOUT_MS;
750
+ for (const id of orderIds)
751
+ if (id)
752
+ this.shadowOrderIds.set(id, expiration);
753
+ this._cleanExpiredLocks();
754
+ }
755
+ /**
756
+ * @param {string[]|Set<string>} orderIds - Order IDs to unlock
757
+ * @returns {void}
758
+ */
759
+ unlockOrders(orderIds) {
760
+ if (!orderIds)
761
+ return;
762
+ for (const id of orderIds)
763
+ if (id)
764
+ this.shadowOrderIds.delete(id);
765
+ this._cleanExpiredLocks();
766
+ }
767
+ /**
768
+ * @param {string} id - Order ID
769
+ * @returns {boolean}
770
+ */
771
+ isOrderLocked(id) {
772
+ const expiresAt = this.shadowOrderIds.get(id);
773
+ if (!expiresAt)
774
+ return false;
775
+ if (Date.now() > expiresAt) {
776
+ this.shadowOrderIds.delete(id);
777
+ return false;
778
+ }
779
+ return true;
780
+ }
781
+ _cleanExpiredLocks() {
782
+ const now = Date.now();
783
+ for (const [id, expiresAt] of this.shadowOrderIds) {
784
+ if (now > expiresAt) {
785
+ this.shadowOrderIds.delete(id);
786
+ }
787
+ }
788
+ }
789
+ _normalizeOrderUpdateOptions(options = {}) {
790
+ if (options === null || typeof options !== 'object' || Array.isArray(options)) {
791
+ throw new TypeError('Order update options must be an object');
792
+ }
793
+ return {
794
+ skipAccounting: options.skipAccounting === true,
795
+ fee: Number.isFinite(Number(options.fee)) ? Number(options.fee) : 0
796
+ };
797
+ }
798
+ _normalizeCommitOptions(options = {}) {
799
+ if (options === null || typeof options !== 'object' || Array.isArray(options)) {
800
+ throw new TypeError('Commit options must be an object');
801
+ }
802
+ return { skipRecalc: options.skipRecalc === true };
803
+ }
804
+ async _updateOrder(order, context = 'updateOrder', options = {}) {
805
+ const updateOptions = this._normalizeOrderUpdateOptions(options);
806
+ return await this._gridLock.acquire(async () => {
807
+ return await this._applyOrderUpdate(order, context, updateOptions);
808
+ });
809
+ }
810
+ async _applyOrderUpdate(order, context = 'updateOrder', options = {}) {
811
+ const updateOptions = this._normalizeOrderUpdateOptions(options);
812
+ const { skipAccounting, fee: normalizedFee } = updateOptions;
813
+ const oldOrder = this.orders.get(order.id);
814
+ const validation = validateOrder(order, oldOrder, context);
815
+ for (const warning of validation.warnings) {
816
+ this.logger.log(warning.message, 'warn');
817
+ }
818
+ if (!validation.isValid && validation.errors.length > 0) {
819
+ const fatalError = validation.errors.find(e => e.isFatal || e.code === 'ILLEGAL_SPREAD_STATE');
820
+ if (fatalError) {
821
+ this.logger.log(fatalError.message, 'error');
822
+ this._state.setIllegalStateSignal({
823
+ id: order.id,
824
+ context,
825
+ message: fatalError.message
826
+ });
827
+ if (this._throwOnIllegalState) {
828
+ const err = new Error(fatalError.message);
829
+ err.code = fatalError.code;
830
+ throw err;
831
+ }
832
+ return false;
833
+ }
834
+ }
835
+ // Ensure a mutable copy before passing to updateOptimisticFreeBalance.
836
+ // validation.normalizedOrder may reference a frozen master-grid order,
837
+ // and _resolveBtsFeeLifecycle mutates btsFeeState on the order object.
838
+ let nextOrder = { ...validation.normalizedOrder };
839
+ // Apply phantom order auto-correction to the normalized order
840
+ const phantomError = validation.errors.find(e => e.code === 'PHANTOM_ORDER');
841
+ if (phantomError && phantomError.autoCorrect) {
842
+ nextOrder = { ...nextOrder, ...phantomError.autoCorrect };
843
+ }
844
+ if (this.accountant) {
845
+ await this.accountant.updateOptimisticFreeBalance(oldOrder, nextOrder, context, normalizedFee, skipAccounting);
846
+ }
847
+ const updatedOrder = deepFreeze({ ...nextOrder });
848
+ const id = order.id;
849
+ Object.values(this._ordersByState).forEach(set => set.delete(id));
850
+ Object.values(this._ordersByType).forEach(set => set.delete(id));
851
+ if (this._ordersByState[updatedOrder.state]) {
852
+ this._ordersByState[updatedOrder.state].add(id);
853
+ }
854
+ if (this._ordersByType[updatedOrder.type]) {
855
+ this._ordersByType[updatedOrder.type].add(id);
856
+ }
857
+ const newMap = cloneMap(this.orders);
858
+ newMap.set(id, updatedOrder);
859
+ this.orders = Object.freeze(newMap);
860
+ this._gridVersion++;
861
+ this._syncWorkingGridFromMasterMutation(id, context);
862
+ if (this._pauseFundRecalc === 0) {
863
+ await this.recalculateFunds();
864
+ }
865
+ this._markGridDirty(context, id);
866
+ return true;
867
+ }
868
+ _syncWorkingGridFromMasterMutation(orderId, context) {
869
+ if (!this._currentWorkingGrid || !this.isPlanningActive()) {
870
+ return;
871
+ }
872
+ try {
873
+ this._currentWorkingGrid.markStale(`master mutation during ${this._rebalanceState.toLowerCase()} (${context})`);
874
+ this._currentWorkingGrid.syncFromMaster(this.orders, orderId, this._gridVersion);
875
+ }
876
+ catch (syncErr) {
877
+ this._currentWorkingGrid.markStale(`working-grid sync failure: ${syncErr.message}`);
878
+ this.logger.log(`[COW] Failed to sync working grid for order ${orderId}: ${syncErr.message}`, 'warn');
879
+ }
880
+ }
881
+ /**
882
+ * @param {Array<import('./types').Order>} updates - Order updates to apply
883
+ * @param {string} [context] - Update context label
884
+ * @param {import('./types').OrderUpdateOptions} [options]
885
+ * @returns {Promise<boolean>}
886
+ */
887
+ async applyGridUpdateBatch(updates, context = 'batch-update', options = {}) {
888
+ const updateOptions = this._normalizeOrderUpdateOptions(options);
889
+ return await this._gridLock.acquire(async () => {
890
+ for (const update of updates) {
891
+ await this._applyOrderUpdate(update, context, updateOptions);
892
+ }
893
+ return true;
894
+ });
895
+ }
896
+ /**
897
+ * Flag the in-memory master grid as dirty so the next flushGridDirty()
898
+ * call persists it. Internal helper — every successful _applyOrderUpdate
899
+ * call ends with this. External callers that mutate the grid through
900
+ * other paths (e.g. raw `this.orders.set(...)` from a refactor) should
901
+ * invoke this explicitly so the dirty-flag invariant still holds.
902
+ *
903
+ * @param {string} [reason='unknown'] - Context label for diagnostics
904
+ * @param {string} [orderId=null] - Order that triggered the mutation
905
+ * @returns {void}
906
+ */
907
+ _markGridDirty(reason = 'unknown', orderId = null) {
908
+ this._gridDirty = true;
909
+ if (this._gridDirtySince == null) {
910
+ this._gridDirtySince = Date.now();
911
+ }
912
+ const key = orderId ? `${reason}:${orderId}` : reason;
913
+ this._gridDirtyReasons.set(key, (this._gridDirtyReasons.get(key) || 0) + 1);
914
+ }
915
+ /**
916
+ * Clear the dirty flag after a successful flush. Internal helper.
917
+ * @returns {void}
918
+ */
919
+ _clearGridDirty() {
920
+ this._gridDirty = false;
921
+ this._gridDirtySince = null;
922
+ this._gridDirtyReasons.clear();
923
+ }
924
+ /**
925
+ * Public read-only access to the dirty flag. Used by tick-end safety
926
+ * nets and by tests/CI to verify the persistence invariant.
927
+ * @returns {boolean}
928
+ */
929
+ isGridDirty() {
930
+ return this._gridDirty === true;
931
+ }
932
+ /**
933
+ * If the master grid has been mutated since the last successful
934
+ * persistGrid() call, persist it now. This is the end-of-tick safety
935
+ * net that catches direct _updateOrder() calls (e.g. partial-fill size
936
+ * updates) that never reach a COW rebalance and therefore never reach
937
+ * a known persistGrid() site.
938
+ *
939
+ * Idempotent: a no-op when the grid is not dirty. Honours
940
+ * suspendGridPersistence(). Returns the underlying persistGrid()
941
+ * result, or {skipped:true, reason:'not-dirty'} when the grid is clean.
942
+ *
943
+ * @param {string} [contextLabel='flush-grid-dirty'] - Label for logs
944
+ * @returns {Promise<{skipped?: boolean, suspended?: boolean, isValid?: boolean, reason?: string}>}
945
+ */
946
+ async flushGridDirty(contextLabel = 'flush-grid-dirty') {
947
+ if (!this._gridDirty) {
948
+ return { skipped: true, reason: 'not-dirty' };
949
+ }
950
+ if (this._gridPersistenceSuspendedReason) {
951
+ this.logger?.log?.(`[PERSISTENCE-FLUSH] Skipping dirty-flush while suspended: ${this._gridPersistenceSuspendedReason}`, 'warn');
952
+ return { skipped: true, suspended: true, reason: this._gridPersistenceSuspendedReason };
953
+ }
954
+ const dirtyCount = this._gridDirtyReasons.size;
955
+ const dirtySince = this._gridDirtySince;
956
+ const result = await this.persistGrid(undefined);
957
+ if (result && result.skipped === true) {
958
+ // Persistence was deferred (suspension, validation, etc.) — keep
959
+ // the dirty flag so a later tick can retry.
960
+ return result;
961
+ }
962
+ if (result && result.isValid === false) {
963
+ this.logger?.log?.(`[PERSISTENCE-FLUSH] Dirty flush validation failed (${contextLabel}): ${result.reason || 'unknown'}`, 'warn');
964
+ return result;
965
+ }
966
+ this._clearGridDirty();
967
+ this.logger?.log?.(`[PERSISTENCE-FLUSH] Flushed ${dirtyCount} dirty mutation context(s) ` +
968
+ `(since ${new Date(dirtySince).toISOString()}) via ${contextLabel}`, 'info');
969
+ return result || { isValid: true };
970
+ }
971
+ /**
972
+ * @param {Array<import('./types').Order>} orders - Filled orders
973
+ * @param {Set<string>} [excl] - Order IDs to exclude
974
+ * @param {Object} [options]
975
+ * @returns {Promise<import('./types').CowRebalanceResult>}
976
+ */
977
+ async processFilledOrders(orders, excl, options) {
978
+ // Step 1: Handle Fills (Accounting & State Updates)
979
+ await this.strategy.processFillsOnly(orders, excl);
980
+ // Step 2: Trigger Safe Rebalance only for actual fills.
981
+ const triggerFills = orders.filter(f => !f.isPartial || f.isDelayedRotationTrigger);
982
+ const shouldRebalance = triggerFills.length > 0;
983
+ if (shouldRebalance) {
984
+ const rebalanceResult = await this.performSafeRebalance(orders, excl);
985
+ return rebalanceResult;
986
+ }
987
+ const { WorkingGrid } = require('./working_grid');
988
+ const workingGrid = new WorkingGrid(this.orders, { baseVersion: this._gridVersion });
989
+ return {
990
+ actions: [],
991
+ stateUpdates: [],
992
+ hadRotation: false,
993
+ workingGrid,
994
+ workingIndexes: workingGrid.getIndexes(),
995
+ workingBoundary: this.boundaryIdx,
996
+ aborted: false
997
+ };
998
+ }
999
+ /**
1000
+ * @returns {Array<import('./types').Order>}
1001
+ */
1002
+ getInitialOrdersToActivate() {
1003
+ // Apply activeOrders limit from config
1004
+ const sellCount = Math.max(0, toFiniteNumber(this.config.activeOrders?.sell, 1));
1005
+ const buyCount = Math.max(0, toFiniteNumber(this.config.activeOrders?.buy, 1));
1006
+ // Get minimum sizes for validation
1007
+ const minOrderSizeFactor = this.config?.gridLimits?.MIN_ORDER_SIZE_FACTOR;
1008
+ const minSellSize = getMinAbsoluteOrderSize(ORDER_TYPES.SELL, this.assets, minOrderSizeFactor);
1009
+ const minBuySize = getMinAbsoluteOrderSize(ORDER_TYPES.BUY, this.assets, minOrderSizeFactor);
1010
+ // Use integer arithmetic for size comparisons to match blockchain behavior
1011
+ const sellPrecision = this.assets?.assetA?.precision;
1012
+ const buyPrecision = this.assets?.assetB?.precision;
1013
+ const minSellSizeInt = floatToBlockchainInt(minSellSize, sellPrecision);
1014
+ const minBuySizeInt = floatToBlockchainInt(minBuySize, buyPrecision);
1015
+ // Get closest virtual sells (lowest prices first = closest to market), limit to sellCount
1016
+ const vSells = this.getOrdersByTypeAndState(ORDER_TYPES.SELL, ORDER_STATES.VIRTUAL)
1017
+ .sort((a, b) => a.price - b.price)
1018
+ .slice(0, sellCount);
1019
+ // Filter by minimum size, then reverse for placement order (highest first)
1020
+ const validSells = vSells
1021
+ .filter(o => floatToBlockchainInt(o.size, sellPrecision) >= minSellSizeInt)
1022
+ .sort((a, b) => b.price - a.price);
1023
+ // Get closest virtual buys (highest prices first = closest to market), limit to buyCount
1024
+ const vBuys = this.getOrdersByTypeAndState(ORDER_TYPES.BUY, ORDER_STATES.VIRTUAL)
1025
+ .sort((a, b) => b.price - a.price)
1026
+ .slice(0, buyCount);
1027
+ // Filter by minimum size, then reverse for placement order (lowest first)
1028
+ const validBuys = vBuys
1029
+ .filter(o => floatToBlockchainInt(o.size, buyPrecision) >= minBuySizeInt)
1030
+ .sort((a, b) => a.price - b.price);
1031
+ return [...validSells, ...validBuys];
1032
+ }
1033
+ /**
1034
+ * Get orders matching the specified type and state.
1035
+ *
1036
+ * @param {string|null} type - Order type (ORDER_TYPES.BUY/SELL/SPREAD) or null for all types
1037
+ * @param {string} state - Order state (ORDER_STATES.ACTIVE/PARTIAL/VIRTUAL)
1038
+ * @returns {Array} Array of matching orders
1039
+ */
1040
+ getOrdersByTypeAndState(type, state) {
1041
+ const result = [];
1042
+ const ids = this._ordersByState[state];
1043
+ if (!ids)
1044
+ return result;
1045
+ for (const id of ids) {
1046
+ const order = this.orders.get(id);
1047
+ // If type is null/undefined, return all orders with matching state
1048
+ // Otherwise, filter by both type and state
1049
+ if (order && order.state === state && (type == null || order.type === type)) {
1050
+ result.push(order);
1051
+ }
1052
+ }
1053
+ return result;
1054
+ }
1055
+ /**
1056
+ * @param {string} type - ORDER_TYPES.BUY or ORDER_TYPES.SELL
1057
+ * @returns {Array<import('./types').Order>}
1058
+ */
1059
+ getPartialOrdersOnSide(type) {
1060
+ return this.getOrdersByTypeAndState(type, ORDER_STATES.PARTIAL);
1061
+ }
1062
+ /**
1063
+ * @returns {boolean}
1064
+ */
1065
+ validateIndices() {
1066
+ for (const [id, order] of this.orders) {
1067
+ if (!order) {
1068
+ this.logger.log(`Index corruption: ${id} exists in orders Map but is null/undefined`, 'error');
1069
+ return false;
1070
+ }
1071
+ if (!order.state) {
1072
+ this.logger.log(`Index corruption: ${id} has no state`, 'error');
1073
+ return false;
1074
+ }
1075
+ if (!order.type) {
1076
+ this.logger.log(`Index corruption: ${id} has no type`, 'error');
1077
+ return false;
1078
+ }
1079
+ if (!this._ordersByState[order.state]?.has(id)) {
1080
+ this.logger.log(`Index mismatch: ${id} not in _ordersByState[${order.state}]`, 'error');
1081
+ return false;
1082
+ }
1083
+ if (!this._ordersByType[order.type]?.has(id)) {
1084
+ this.logger.log(`Index mismatch: ${id} not in _ordersByType[${order.type}]`, 'error');
1085
+ return false;
1086
+ }
1087
+ }
1088
+ for (const [state, orderIds] of Object.entries(this._ordersByState)) {
1089
+ for (const id of orderIds) {
1090
+ if (!id || !this.orders.has(id)) {
1091
+ this.logger.log(`Index orphan: ${id} in _ordersByState[${state}] but not in orders Map`, 'error');
1092
+ return false;
1093
+ }
1094
+ }
1095
+ }
1096
+ for (const [type, orderIds] of Object.entries(this._ordersByType)) {
1097
+ for (const id of orderIds) {
1098
+ if (!id || !this.orders.has(id)) {
1099
+ this.logger.log(`Index orphan: ${id} in _ordersByType[${type}] but not in orders Map`, 'error');
1100
+ return false;
1101
+ }
1102
+ }
1103
+ }
1104
+ return true;
1105
+ }
1106
+ /**
1107
+ * @returns {boolean}
1108
+ */
1109
+ assertIndexConsistency() {
1110
+ if (!this.validateIndices()) {
1111
+ this.logger.log('CRITICAL: Index corruption detected! Attempting repair...', 'error');
1112
+ return this._repairIndices();
1113
+ }
1114
+ return true;
1115
+ }
1116
+ _repairIndices() {
1117
+ try {
1118
+ const rebuiltByState = {
1119
+ [ORDER_STATES.VIRTUAL]: new Set(),
1120
+ [ORDER_STATES.ACTIVE]: new Set(),
1121
+ [ORDER_STATES.PARTIAL]: new Set()
1122
+ };
1123
+ const rebuiltByType = {
1124
+ [ORDER_TYPES.BUY]: new Set(),
1125
+ [ORDER_TYPES.SELL]: new Set(),
1126
+ [ORDER_TYPES.SPREAD]: new Set()
1127
+ };
1128
+ for (const [id, order] of this.orders) {
1129
+ if (order && order.state && order.type) {
1130
+ rebuiltByState[order.state]?.add(id);
1131
+ rebuiltByType[order.type]?.add(id);
1132
+ }
1133
+ else {
1134
+ this.logger.log(`Skipping corrupted order ${id} during index repair`, 'warn');
1135
+ }
1136
+ }
1137
+ this._ordersByState = rebuiltByState;
1138
+ this._ordersByType = rebuiltByType;
1139
+ if (this.validateIndices()) {
1140
+ this.logger.log('✓ Index repair successful', 'info');
1141
+ return true;
1142
+ }
1143
+ this.logger.log('✗ Index repair failed - structure is damaged', 'error');
1144
+ return false;
1145
+ }
1146
+ catch (e) {
1147
+ this.logger.log(`Index repair failed with exception: ${e.message}`, 'error');
1148
+ return false;
1149
+ }
1150
+ }
1151
+ /**
1152
+ * @returns {Object|null} The consumed signal or null
1153
+ */
1154
+ consumeIllegalStateSignal() {
1155
+ return this._state.consumeIllegalStateSignal();
1156
+ }
1157
+ /**
1158
+ * @returns {Object|null} The consumed signal or null
1159
+ */
1160
+ consumeAccountingFailureSignal() {
1161
+ return this._state.consumeAccountingFailureSignal();
1162
+ }
1163
+ /**
1164
+ * @param {Object} BitShares - BitShares API instance
1165
+ * @param {Function} batchCb - Batch callback
1166
+ * @returns {Promise<Object>}
1167
+ */
1168
+ async checkSpreadCondition(BitShares, batchCb) {
1169
+ return await Grid.checkSpreadCondition(this, BitShares, batchCb);
1170
+ }
1171
+ /**
1172
+ * @param {Function} batchCb - Batch callback
1173
+ * @returns {Promise<Object>}
1174
+ */
1175
+ async checkGridHealth(batchCb) {
1176
+ return await Grid.checkGridHealth(this, batchCb);
1177
+ }
1178
+ /**
1179
+ * @returns {Object} Current spread calculation
1180
+ */
1181
+ calculateCurrentSpread() {
1182
+ return Grid.calculateCurrentSpread(this);
1183
+ }
1184
+ /**
1185
+ * @returns {import('./types').DriftCheckResult}
1186
+ */
1187
+ checkFundDriftAfterFills() {
1188
+ if (!this.assets || !hasValidAccountTotals(this.accountTotals)) {
1189
+ return { isValid: true, reason: 'Skipped: missing assets or totals' };
1190
+ }
1191
+ return checkFundDrift(this.orders, this.accountTotals, this.assets, this.config?.gridLimits ?? null);
1192
+ }
1193
+ /**
1194
+ * @param {Object|number} [pipelineSignals] - Pipeline state signals or queue length
1195
+ * @returns {import('./types').PipelineEmptyResult}
1196
+ */
1197
+ isPipelineEmpty(pipelineSignals = 0) {
1198
+ const normalizedSignals = (typeof pipelineSignals === 'number')
1199
+ ? { incomingFillQueueLength: pipelineSignals }
1200
+ : (pipelineSignals || {});
1201
+ const incomingFillQueueLength = toFiniteNumber(normalizedSignals.incomingFillQueueLength);
1202
+ const shadowLocks = toFiniteNumber(normalizedSignals.shadowLocks);
1203
+ const batchInFlight = !!normalizedSignals.batchInFlight;
1204
+ const recoveryInFlight = !!normalizedSignals.recoveryInFlight;
1205
+ const broadcasting = !!normalizedSignals.broadcasting;
1206
+ this._cleanExpiredLocks();
1207
+ const reasons = [];
1208
+ // invariant: _gridSidesUpdated is pre-cleared by executeMaintenanceLogic
1209
+ // before calling isPipelineEmpty (see modules/dexbot_maintenance_runtime.ts:1378).
1210
+ // Any new caller must pre-clear or add its own gating to avoid a permanently
1211
+ // blocked pipeline.
1212
+ if (incomingFillQueueLength > 0) {
1213
+ reasons.push(`${incomingFillQueueLength} fills queued`);
1214
+ }
1215
+ if (this.ordersNeedingPriceCorrection.length > 0) {
1216
+ reasons.push(`${this.ordersNeedingPriceCorrection.length} corrections pending`);
1217
+ }
1218
+ if (shadowLocks > 0) {
1219
+ reasons.push(`${shadowLocks} shadow lock(s) active`);
1220
+ }
1221
+ if (batchInFlight) {
1222
+ reasons.push('batch broadcast in-flight');
1223
+ }
1224
+ if (recoveryInFlight) {
1225
+ reasons.push('recovery sync in-flight');
1226
+ }
1227
+ if (broadcasting || this._state.isBroadcastingActive()) {
1228
+ reasons.push('broadcasting active orders');
1229
+ }
1230
+ if (reasons.length > 0 && !this._pipelineBlockedSince) {
1231
+ this._pipelineBlockedSince = Date.now();
1232
+ this._state.markPipelineBlocked();
1233
+ }
1234
+ else if (reasons.length === 0) {
1235
+ this._pipelineBlockedSince = null;
1236
+ this._state.markPipelineClear();
1237
+ }
1238
+ return {
1239
+ isEmpty: reasons.length === 0,
1240
+ reasons
1241
+ };
1242
+ }
1243
+ /**
1244
+ * @returns {boolean} Whether stale operations were cleared
1245
+ */
1246
+ clearStalePipelineOperations() {
1247
+ if (!this._pipelineBlockedSince)
1248
+ return false;
1249
+ const age = Date.now() - this._pipelineBlockedSince;
1250
+ if (age < PIPELINE_TIMING.TIMEOUT_MS)
1251
+ return false;
1252
+ this.ordersNeedingPriceCorrection = [];
1253
+ this._pipelineBlockedSince = null;
1254
+ this._state.markPipelineClear();
1255
+ return true;
1256
+ }
1257
+ /**
1258
+ * @returns {import('./types').PipelineHealth}
1259
+ */
1260
+ getPipelineHealth() {
1261
+ const blockedDuration = this._pipelineBlockedSince
1262
+ ? Date.now() - this._pipelineBlockedSince
1263
+ : 0;
1264
+ return {
1265
+ isBlocked: this._pipelineBlockedSince !== null,
1266
+ blockedDurationMs: blockedDuration,
1267
+ hasStalled: blockedDuration > PIPELINE_TIMING.TIMEOUT_MS,
1268
+ recoveryAttempted: this._recoveryAttempted,
1269
+ correctionsPending: this.ordersNeedingPriceCorrection.length,
1270
+ gridSidesUpdated: this._gridSidesUpdated?.size || 0
1271
+ };
1272
+ }
1273
+ /**
1274
+ * @param {Map<string, import('./types').Order>} targetGrid
1275
+ * @param {number} targetBoundary
1276
+ * @returns {Object}
1277
+ */
1278
+ reconcileGrid(targetGrid, targetBoundary) {
1279
+ return reconcileGrid(this.orders, targetGrid, targetBoundary, {
1280
+ logger: (msg, level) => this.logger.log(msg, level),
1281
+ dustThresholdPercent: this.config?.gridLimits?.PARTIAL_DUST_THRESHOLD_PERCENTAGE
1282
+ });
1283
+ }
1284
+ /**
1285
+ * @param {Array} [fills] - Fill events triggering rebalance
1286
+ * @param {Set<string>} [excludeIds] - Order IDs to exclude
1287
+ * @returns {Promise<import('./types').CowRebalanceResult>}
1288
+ */
1289
+ async performSafeRebalance(fills = [], excludeIds = new Set()) {
1290
+ this.logger.log("[SAFE-REBALANCE] Starting with COW...", "info");
1291
+ return await this._gridLock.acquire(async () => {
1292
+ return await this._applySafeRebalanceCOW(fills, excludeIds);
1293
+ });
1294
+ }
1295
+ async _applySafeRebalanceCOW(fills = [], excludeIds = new Set()) {
1296
+ const cowEngine = this._getCOWEngine();
1297
+ if (!cowEngine) {
1298
+ return buildAbortedResult('COW Engine not initialized (assets not available)');
1299
+ }
1300
+ this._setRebalanceState(REBALANCE_STATES.REBALANCING);
1301
+ const result = await cowEngine.execute({
1302
+ masterGrid: this.orders,
1303
+ gridVersion: this._gridVersion,
1304
+ boundaryIdx: this.boundaryIdx,
1305
+ funds: this.getChainFundsSnapshot(),
1306
+ fills,
1307
+ excludeIds
1308
+ });
1309
+ if (result.aborted) {
1310
+ this._clearWorkingGridRef();
1311
+ return result;
1312
+ }
1313
+ this._currentWorkingGrid = result.workingGrid;
1314
+ return result;
1315
+ }
1316
+ _reconcileGridCOW(targetGrid, targetBoundary, workingGrid) {
1317
+ const result = this.reconcileGrid(targetGrid, targetBoundary);
1318
+ if (result.aborted)
1319
+ return result;
1320
+ const actions = optimizeRebalanceActions(result.actions || [], this.orders);
1321
+ projectTargetToWorkingGrid(workingGrid, targetGrid, { actions });
1322
+ return {
1323
+ ...result,
1324
+ actions,
1325
+ ...summarizeActions(actions)
1326
+ };
1327
+ }
1328
+ _validateWorkingGridFunds(workingGrid, projectedFunds) {
1329
+ return validateWorkingGridFunds(workingGrid, projectedFunds, {
1330
+ buyPrecision: this.assets?.assetB?.precision,
1331
+ sellPrecision: this.assets?.assetA?.precision
1332
+ }, this.assets);
1333
+ }
1334
+ _calculateRequiredFundsFromGrid(workingGrid, precisions = {}) {
1335
+ return calculateRequiredFunds(workingGrid, {
1336
+ buyPrecision: precisions.buyPrecision || this.assets?.assetB?.precision,
1337
+ sellPrecision: precisions.sellPrecision || this.assets?.assetA?.precision
1338
+ });
1339
+ }
1340
+ _getCowComparePrecisions() {
1341
+ const buyPrecisionRaw = this.assets?.assetB?.precision;
1342
+ const sellPrecisionRaw = this.assets?.assetA?.precision;
1343
+ const incrementPercentRaw = this.config?.incrementPercent;
1344
+ const buyPrecision = Number(buyPrecisionRaw);
1345
+ const sellPrecision = Number(sellPrecisionRaw);
1346
+ const incrementPercent = Number(incrementPercentRaw);
1347
+ if (!Number.isFinite(buyPrecision) || !Number.isFinite(sellPrecision)) {
1348
+ throw new Error(`CRITICAL: Missing asset precision for COW compare (buy=${buyPrecisionRaw}, sell=${sellPrecisionRaw}). ` +
1349
+ `Refusing commit-time delta comparison.`);
1350
+ }
1351
+ if (!Number.isFinite(incrementPercent) || incrementPercent <= 0) {
1352
+ throw new Error(`CRITICAL: Missing/invalid incrementPercent for COW compare (${incrementPercentRaw}). ` +
1353
+ `Refusing commit-time delta comparison.`);
1354
+ }
1355
+ // Relative price threshold = 1/10 of one configured increment step.
1356
+ // Example: incrementPercent=0.5 -> relative tolerance ratio=0.0005 (0.05%).
1357
+ const priceRelativeTolerance = incrementPercent / 1000;
1358
+ return {
1359
+ buyPrecision,
1360
+ sellPrecision,
1361
+ priceRelativeTolerance
1362
+ };
1363
+ }
1364
+ _buildStateUpdates(actions, masterGrid) {
1365
+ return buildStateUpdates(actions, masterGrid);
1366
+ }
1367
+ _buildAbortedCOWResult(reason) {
1368
+ return buildAbortedResult(reason);
1369
+ }
1370
+ async _commitWorkingGrid(workingGrid, workingIndexes, workingBoundary, options = {}) {
1371
+ const { skipRecalc } = this._normalizeCommitOptions(options);
1372
+ const startTime = Date.now();
1373
+ const stats = workingGrid.getMemoryStats();
1374
+ let committed = false;
1375
+ let comparePrecisions;
1376
+ try {
1377
+ comparePrecisions = this._getCowComparePrecisions();
1378
+ }
1379
+ catch (precisionErr) {
1380
+ this.logger.log(`[COW] ${precisionErr.message}`, 'error');
1381
+ this._clearWorkingGridRef();
1382
+ return false;
1383
+ }
1384
+ const preCommitGuard = evaluateCommit(workingGrid, {
1385
+ hasLock: false,
1386
+ currentVersion: this._gridVersion,
1387
+ masterGrid: this.orders,
1388
+ comparePrecisions
1389
+ });
1390
+ if (!preCommitGuard.canCommit) {
1391
+ this.logger.log(`[COW] ${preCommitGuard.reason}`, preCommitGuard.level || 'warn');
1392
+ this._clearWorkingGridRef();
1393
+ return false;
1394
+ }
1395
+ await this._gridLock.acquire(async () => {
1396
+ const lockCommitGuard = evaluateCommit(workingGrid, {
1397
+ hasLock: true,
1398
+ currentVersion: this._gridVersion,
1399
+ masterGrid: this.orders,
1400
+ comparePrecisions
1401
+ });
1402
+ if (!lockCommitGuard.canCommit) {
1403
+ this.logger.log(`[COW] ${lockCommitGuard.reason}`, lockCommitGuard.level || 'warn');
1404
+ this._clearWorkingGridRef();
1405
+ return;
1406
+ }
1407
+ this.logger.log(`[COW] Committing working grid: ${stats.size} orders, ${stats.modified} modified`, 'debug');
1408
+ const finalMap = workingGrid.toMap();
1409
+ // RC-4: Deep-freeze all modified orders before committing to master state
1410
+ // Ensures COW immutability invariants are maintained for all grid entries.
1411
+ for (const [id, order] of finalMap.entries()) {
1412
+ if (order && !Object.isFrozen(order)) {
1413
+ deepFreeze(order);
1414
+ }
1415
+ }
1416
+ this.orders = Object.freeze(finalMap);
1417
+ this.boundaryIdx = workingBoundary;
1418
+ this._gridVersion++;
1419
+ committed = true;
1420
+ const freshIndexes = workingGrid.getIndexes();
1421
+ this._ordersByState = {
1422
+ [ORDER_STATES.VIRTUAL]: freshIndexes[ORDER_STATES.VIRTUAL] || new Set(),
1423
+ [ORDER_STATES.ACTIVE]: freshIndexes[ORDER_STATES.ACTIVE] || new Set(),
1424
+ [ORDER_STATES.PARTIAL]: freshIndexes[ORDER_STATES.PARTIAL] || new Set()
1425
+ };
1426
+ this._ordersByType = {
1427
+ [ORDER_TYPES.BUY]: freshIndexes[ORDER_TYPES.BUY] || new Set(),
1428
+ [ORDER_TYPES.SELL]: freshIndexes[ORDER_TYPES.SELL] || new Set(),
1429
+ [ORDER_TYPES.SPREAD]: freshIndexes[ORDER_TYPES.SPREAD] || new Set()
1430
+ };
1431
+ });
1432
+ if (!committed) {
1433
+ this._clearWorkingGridRef();
1434
+ return false;
1435
+ }
1436
+ try {
1437
+ if (!skipRecalc) {
1438
+ await this.recalculateFunds();
1439
+ }
1440
+ const duration = Date.now() - startTime;
1441
+ this.logger.log(`[COW] Grid committed in ${duration}ms`, 'debug');
1442
+ if (stats.size > COW_PERFORMANCE.GRID_MEMORY_WARNING) {
1443
+ this.logger.log(`[COW] Warning: Large grid size (${stats.size} orders). Peak memory: ~${Math.round(stats.estimatedBytes / 1024)}KB`, 'warn');
1444
+ }
1445
+ }
1446
+ catch (recalcErr) {
1447
+ this.logger.log(`[COW] Fund recalculation failed post-commit: ${recalcErr.message}`, 'error');
1448
+ this._recoveryState = this._recoveryState || {};
1449
+ this._recoveryState.lastFailureAt = Date.now();
1450
+ }
1451
+ finally {
1452
+ this._clearWorkingGridRef();
1453
+ }
1454
+ return true;
1455
+ }
1456
+ /**
1457
+ * @param {Object} [options]
1458
+ * @param {boolean} [options.allowBootstrapTransient]
1459
+ * @returns {import('./types').PersistenceValidationResult}
1460
+ */
1461
+ validateGridStateForPersistence(options = {}) {
1462
+ const result = validateGridForPersistence(this.orders, this.accountTotals);
1463
+ const allowBootstrapTransient = options.allowBootstrapTransient !== false;
1464
+ if (!result.isValid && allowBootstrapTransient && this._state.isBootstrapping()) {
1465
+ this.logger.log(`[BOOTSTRAP] Transient state (expected): ${result.reason}`, 'debug');
1466
+ return { isValid: true, reason: null };
1467
+ }
1468
+ return result;
1469
+ }
1470
+ /**
1471
+ * @param {string} [reason]
1472
+ * @returns {void}
1473
+ */
1474
+ suspendGridPersistence(reason = 'suspended') {
1475
+ this._gridPersistenceSuspendedReason = reason;
1476
+ }
1477
+ /**
1478
+ * @param {string} [reason]
1479
+ * @returns {void}
1480
+ */
1481
+ resumeGridPersistence(reason = null) {
1482
+ if (!this._gridPersistenceSuspendedReason)
1483
+ return;
1484
+ this.logger.log(`[PERSISTENCE-GATE] Resuming grid persistence${reason ? ` (${reason})` : ''}`, 'info');
1485
+ this._gridPersistenceSuspendedReason = null;
1486
+ }
1487
+ /**
1488
+ * @param {Array<Object>} [snapshotOrders] - Optional explicit orders to persist.
1489
+ * When provided, this list is persisted as-is and the live `manager.orders`
1490
+ * map is not touched. This is the only race-free way to persist a freshly
1491
+ * built grid (e.g. from the startup `storeGrid` callback) without briefly
1492
+ * swapping the live map and exposing it to concurrent readers.
1493
+ * @returns {Promise<import('./types').PersistenceValidationResult>}
1494
+ */
1495
+ async persistGrid(snapshotOrders) {
1496
+ if (this._gridPersistenceSuspendedReason) {
1497
+ this.logger.log(`[PERSISTENCE-GATE] Skipping grid persistence while suspended: ${this._gridPersistenceSuspendedReason}`, 'warn');
1498
+ return { isValid: true, skipped: true, suspended: true, reason: this._gridPersistenceSuspendedReason };
1499
+ }
1500
+ const validation = this.validateGridStateForPersistence();
1501
+ if (!validation.isValid) {
1502
+ this.logger.log(`[PERSISTENCE-GATE] Skipping persistence of corrupted state: ${validation.reason}`, 'warn');
1503
+ return validation;
1504
+ }
1505
+ await persistGridSnapshot(this, this.accountOrders, snapshotOrders);
1506
+ // On a successful live-grid persist (the default — no explicit
1507
+ // snapshotOrders was passed in), clear the dirty flag so that
1508
+ // a subsequent end-of-tick flushGridDirty() call sees the grid
1509
+ // as clean and skips the second snapshot write. When the caller
1510
+ // passes an explicit snapshotOrders (e.g. from the startup
1511
+ // storeGrid callback), the dirty flag is for the LIVE grid, not
1512
+ // the supplied snapshot, so we leave it alone.
1513
+ if (snapshotOrders === undefined && this._gridDirty) {
1514
+ this._clearGridDirty();
1515
+ }
1516
+ return validation;
1517
+ }
1518
+ /**
1519
+ * @returns {import('./types').Metrics}
1520
+ */
1521
+ getMetrics() {
1522
+ return {
1523
+ ...this._metrics,
1524
+ state: this._state.getState(),
1525
+ currentTime: Date.now()
1526
+ };
1527
+ }
1528
+ _projectTargetToWorkingGrid(workingGrid, targetGrid) {
1529
+ return projectTargetToWorkingGrid(workingGrid, targetGrid);
1530
+ }
1531
+ _summarizeCowActions(actions) {
1532
+ return summarizeActions(actions);
1533
+ }
1534
+ _evaluateWorkingGridCommit(workingGrid, hasLock = false) {
1535
+ let comparePrecisions;
1536
+ try {
1537
+ comparePrecisions = this._getCowComparePrecisions();
1538
+ }
1539
+ catch (precisionErr) {
1540
+ return {
1541
+ canCommit: false,
1542
+ reason: precisionErr.message,
1543
+ level: 'error'
1544
+ };
1545
+ }
1546
+ return evaluateCommit(workingGrid, {
1547
+ hasLock,
1548
+ currentVersion: this._gridVersion,
1549
+ masterGrid: this.orders,
1550
+ comparePrecisions
1551
+ });
1552
+ }
1553
+ get _rebalanceState() {
1554
+ return this._state.getRebalanceState();
1555
+ }
1556
+ set _rebalanceState(value) {
1557
+ this._state.setRebalanceState(value);
1558
+ }
1559
+ get _lastIllegalState() {
1560
+ return this._state.signals?.lastIllegalState || null;
1561
+ }
1562
+ set _lastIllegalState(value) {
1563
+ if (value) {
1564
+ this._state.setIllegalStateSignal(value);
1565
+ }
1566
+ }
1567
+ get _lastAccountingFailure() {
1568
+ return this._state.signals?.lastAccountingFailure || null;
1569
+ }
1570
+ set _lastAccountingFailure(value) {
1571
+ if (value) {
1572
+ this._state.setAccountingFailureSignal(value);
1573
+ }
1574
+ }
1575
+ get _recoveryState() {
1576
+ return this._state.recovery;
1577
+ }
1578
+ set _recoveryState(value) {
1579
+ const fallback = {
1580
+ attemptCount: 0,
1581
+ lastAttemptAt: 0,
1582
+ inFlight: false,
1583
+ lastFailureAt: 0,
1584
+ structuralResyncRequested: false
1585
+ };
1586
+ this._state.recovery = {
1587
+ ...fallback,
1588
+ ...(value && typeof value === 'object' ? value : {})
1589
+ };
1590
+ }
1591
+ get _gridRegenState() {
1592
+ return this._state.gridRegen;
1593
+ }
1594
+ set _gridRegenState(value) {
1595
+ if (!value || typeof value !== 'object')
1596
+ return;
1597
+ const defaultSide = { armed: true, lastTriggeredAt: 0 };
1598
+ this._state.gridRegen = {
1599
+ buy: { ...defaultSide, ...(value.buy || {}) },
1600
+ sell: { ...defaultSide, ...(value.sell || {}) }
1601
+ };
1602
+ }
1603
+ }
1604
+ module.exports = { OrderManager };
1605
+ //# sourceMappingURL=manager.js.map