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,1452 @@
1
+ "use strict";
2
+ /**
3
+ * DEXBot2 Credential Daemon Policy Engine
4
+ *
5
+ * Evaluates policies before key material is decrypted. Inspired by OWS pattern.
6
+ * Supports declarative rules (fast, in-process) + executable hooks (subprocess).
7
+ * AND semantics: all policies must allow, or signing is denied.
8
+ * Default-deny on errors: validation failures, executable timeouts, etc.
9
+ */
10
+ const { path } = require('./path_api');
11
+ const { randomBytes, createHmac, timingSafeEqual } = require('./crypto/sync');
12
+ const { BitShares } = require('./bitshares_client');
13
+ const { isPositiveInt } = require('./order/utils/math');
14
+ const { parseJsonWithComments } = require('./order/utils/system');
15
+ const { FEE_PARAMETERS } = require('./constants');
16
+ const { getCredentialReadyFilePath, assertPrivatePathSecurity } = require('./credential_runtime');
17
+ const { PATHS } = require('./paths');
18
+ const Logger = require('./logger');
19
+ const { getStorage } = require('./storage');
20
+ const storage = getStorage();
21
+ const { runtime } = require('./runtime');
22
+ const { ensureDir, readJSON, safeUnlink, writeJSON } = require('./utils/fs_utils');
23
+ // Module-scope logger for library-style helpers that don't own a process
24
+ // logger. The class honours PM2 auto-quiet and routes to a log file when one
25
+ // is configured, matching the rest of the codebase.
26
+ const policyLogger = new Logger('credential-policy');
27
+ const BOTS_JSON_PATH = PATHS.PROFILES.BOTS_JSON;
28
+ const ASSET_OBJECT_ID_PATTERN = /^1\.3\.\d+$/;
29
+ const POLICY_DENIED_PREFIX = 'POLICY_DENIED: ';
30
+ const EXECUTABLE_TIMEOUT_MS = 5000;
31
+ // BitShares operation types that DEXBot2 uses
32
+ const ALLOWED_OP_TYPES = [
33
+ 'transfer',
34
+ 'limit_order_create',
35
+ 'limit_order_cancel',
36
+ 'call_order_update',
37
+ 'liquidity_pool_exchange',
38
+ 'limit_order_update',
39
+ 'credit_offer_accept',
40
+ 'credit_deal_repay',
41
+ 'credit_deal_update',
42
+ ];
43
+ // Hardcoded baseline policy used when resolving policy layers in-process.
44
+ // The credential daemon now requires an explicit on-disk policy file and
45
+ // fails closed on startup/reload mismatches.
46
+ const BUILTIN_DEFAULT_POLICY = Object.freeze({
47
+ allowedOps: Object.freeze({
48
+ limit_order_create: null,
49
+ limit_order_cancel: null,
50
+ limit_order_update: null,
51
+ call_order_update: null,
52
+ liquidity_pool_exchange: null,
53
+ transfer: null,
54
+ credit_offer_accept: null,
55
+ credit_deal_repay: null,
56
+ credit_deal_update: null,
57
+ }),
58
+ maxOpsPerBatch: 200,
59
+ allowedAssetIds: null,
60
+ executable: null,
61
+ });
62
+ const policyCache = new Map();
63
+ const assetRefResolutionCache = new Map();
64
+ let _externalAssetResolver = null;
65
+ /**
66
+ * Register an external asset-ref resolver used by the credential daemon.
67
+ * The daemon's native chain client is connected and can resolve symbol names,
68
+ * whereas the global BitShares object may not be initialised in daemon context.
69
+ */
70
+ function setExternalAssetResolver(resolver) {
71
+ _externalAssetResolver = resolver;
72
+ }
73
+ async function resolveAssetRefToId(assetRef) {
74
+ if (!assetRef || typeof assetRef !== 'string')
75
+ return null;
76
+ const cacheKey = String(assetRef);
77
+ if (assetRefResolutionCache.has(cacheKey)) {
78
+ return assetRefResolutionCache.get(cacheKey);
79
+ }
80
+ let resolvedId = null;
81
+ // Try external resolver first (credential daemon with native chain client).
82
+ // Only registered by the daemon; the legacy bot process path never sets one.
83
+ // If it fails (e.g. native client not yet connected), fall through to the
84
+ // legacy BitShares path below.
85
+ if (_externalAssetResolver) {
86
+ try {
87
+ const result = await _externalAssetResolver(cacheKey);
88
+ if (result) {
89
+ assetRefResolutionCache.set(cacheKey, result);
90
+ return result;
91
+ }
92
+ }
93
+ catch (_) {
94
+ // fall through — native client may not be connected yet
95
+ }
96
+ // Don't cache null from external resolver; the native client may not
97
+ // be connected yet and would have returned a transient failure.
98
+ }
99
+ try {
100
+ if (ASSET_OBJECT_ID_PATTERN.test(cacheKey)) {
101
+ resolvedId = cacheKey;
102
+ }
103
+ else if (BitShares?.db?.lookup_asset_symbols) {
104
+ const result = await BitShares.db.lookup_asset_symbols([cacheKey]);
105
+ const asset = Array.isArray(result) ? result[0] : null;
106
+ resolvedId = asset?.id ? String(asset.id) : null;
107
+ }
108
+ else if (BitShares?.db?.get_assets) {
109
+ const result = await BitShares.db.get_assets([cacheKey]);
110
+ const asset = Array.isArray(result) ? result[0] : null;
111
+ resolvedId = asset?.id ? String(asset.id) : null;
112
+ }
113
+ }
114
+ catch (_) {
115
+ resolvedId = null;
116
+ }
117
+ if (resolvedId)
118
+ assetRefResolutionCache.set(cacheKey, resolvedId);
119
+ return resolvedId;
120
+ }
121
+ async function resolveConfiguredAssetRefs(refs, label) {
122
+ const resolved = [];
123
+ for (const ref of refs) {
124
+ if (!ref)
125
+ continue;
126
+ const normalizedRef = String(ref);
127
+ if (ASSET_OBJECT_ID_PATTERN.test(normalizedRef)) {
128
+ resolved.push(normalizedRef);
129
+ continue;
130
+ }
131
+ const resolvedId = await resolveAssetRefToId(normalizedRef);
132
+ if (!resolvedId) {
133
+ return {
134
+ ok: false,
135
+ reason: `unable to resolve asset ref "${normalizedRef}" from ${label}`,
136
+ };
137
+ }
138
+ resolved.push(String(resolvedId));
139
+ }
140
+ return { ok: true, values: resolved };
141
+ }
142
+ function normalizeGrapheneCollateralRatio(value) {
143
+ const numeric = Number(value);
144
+ if (!Number.isFinite(numeric) || numeric <= 0)
145
+ return null;
146
+ const denom = FEE_PARAMETERS.GRAPHENE_COLLATERAL_RATIO_DENOM;
147
+ return numeric >= denom ? numeric / denom : numeric;
148
+ }
149
+ function createMinimalPolicyConfig() {
150
+ return {
151
+ accounts: {},
152
+ };
153
+ }
154
+ function readPolicyConfigDetailed(filePath) {
155
+ if (!storage.exists(filePath)) {
156
+ return {
157
+ status: 'missing',
158
+ config: null,
159
+ error: `config file not found: ${filePath}`,
160
+ };
161
+ }
162
+ let raw;
163
+ try {
164
+ raw = readJSON(filePath);
165
+ }
166
+ catch (error) {
167
+ return {
168
+ status: 'invalid',
169
+ config: null,
170
+ error: `failed to load config: ${error.message}`,
171
+ };
172
+ }
173
+ const { valid, errors } = validatePolicyConfig(raw);
174
+ if (!valid) {
175
+ return {
176
+ status: 'invalid',
177
+ config: null,
178
+ error: `config validation failed: ${errors.join('; ')}`,
179
+ };
180
+ }
181
+ return {
182
+ status: 'ok',
183
+ config: raw,
184
+ error: null,
185
+ };
186
+ }
187
+ /**
188
+ * Check that a policy config file has restrictive permissions (0o600).
189
+ * MIGRATION: Auto-remediates legacy 0o644 mode with a warning, matching
190
+ * the behavior of checkKeysFileSecurity in chain_keys.ts.
191
+ *
192
+ * @param {string} filePath - Path to daemon-policies.json
193
+ */
194
+ function checkPolicyFileSecurity(filePath) {
195
+ if (!storage.exists(filePath))
196
+ return;
197
+ try {
198
+ assertPrivatePathSecurity(filePath, { expectedType: 'file', requiredMode: 0o600 });
199
+ }
200
+ catch (err) {
201
+ const stat = storage.lstat(filePath);
202
+ const mode = stat.mode & 0o777;
203
+ if (mode === 0o644 && !stat.isSymbolicLink()) {
204
+ storage.chmod(filePath, 0o600);
205
+ policyLogger.warn(`[security] Auto-fixed ${filePath} permissions from 0o644 to 0o600. Run: chmod 600 profiles/daemon-policies.json`);
206
+ return;
207
+ }
208
+ throw err;
209
+ }
210
+ }
211
+ /**
212
+ * Ensure daemon-policies.json exists before the credential daemon starts.
213
+ * Missing files are initialized to a minimal strict-compatible policy; invalid
214
+ * existing files still fail closed and are not overwritten.
215
+ *
216
+ * @param {string} filePath - Path to daemon-policies.json
217
+ * @returns {object} Valid parsed config
218
+ * @throws {Error} When the existing file is invalid or creation fails
219
+ */
220
+ function ensurePolicyConfig(filePath) {
221
+ if (!storage.exists(filePath)) {
222
+ try {
223
+ storage.ensureDir(path.dirname(filePath));
224
+ storage.writeJSON(filePath, createMinimalPolicyConfig(), { mode: 0o600, flag: 'wx' });
225
+ }
226
+ catch (err) {
227
+ if (err.code !== 'EEXIST') {
228
+ const wrapped = new Error(`Failed to create required policy config: ${err.message}`);
229
+ wrapped.code = 'POLICY_CONFIG_CREATE_FAILED';
230
+ throw wrapped;
231
+ }
232
+ }
233
+ }
234
+ return loadRequiredPolicyConfig(filePath);
235
+ }
236
+ /**
237
+ * Load and parse daemon-policies.json. Returns normalized config or throws on
238
+ * error/absence (daemon uses loadRequiredPolicyConfig which throws).
239
+ *
240
+ * @param {string} filePath - Path to daemon-policies.json
241
+ * @param {object} [options={}] - Options
242
+ * @param {boolean} [options.forceReload=false] - If true, bypass cache and reload from disk
243
+ */
244
+ function loadPolicyConfig(filePath, options = {}) {
245
+ const forceReload = options.forceReload || false;
246
+ if (!forceReload && policyCache.has(filePath)) {
247
+ return policyCache.get(filePath);
248
+ }
249
+ const detailed = readPolicyConfigDetailed(filePath);
250
+ if (detailed.status !== 'ok') {
251
+ policyLogger.warn(`[policy] ${detailed.error} — using builtin defaults`);
252
+ policyCache.set(filePath, null);
253
+ return null;
254
+ }
255
+ policyCache.set(filePath, detailed.config);
256
+ return detailed.config;
257
+ }
258
+ /**
259
+ * Reload daemon-policies.json from disk with caller-controlled failure
260
+ * semantics. Single source of truth for both the SIGHUP handler
261
+ * (operator-initiated, fail closed) and the fs.watch debounce
262
+ * (auto-provision, keep last-good in-memory config).
263
+ *
264
+ * @param {string} filePath - Path to daemon-policies.json
265
+ * @param {object} [options={}] - Options
266
+ * @param {boolean} [options.strict=false] - When true, rethrows the load
267
+ * error so the caller can decide the response (e.g. shutdown). When
268
+ * false (default), returns null on failure so the caller can keep the
269
+ * existing in-memory config and log a warning.
270
+ * @returns {object|null} Parsed config on success, null on non-strict failure
271
+ */
272
+ function reloadPolicyFromDisk(filePath, options = {}) {
273
+ const strict = options.strict === true;
274
+ try {
275
+ return loadRequiredPolicyConfig(filePath);
276
+ }
277
+ catch (err) {
278
+ if (strict)
279
+ throw err;
280
+ policyLogger.warn(`[policy] Reload from ${filePath} failed: ${err.message} — keeping in-memory config`);
281
+ return null;
282
+ }
283
+ }
284
+ /**
285
+ * Load daemon-policies.json as a required runtime dependency.
286
+ * Used by the credential daemon, which fails closed on missing/invalid policy.
287
+ *
288
+ * @param {string} filePath - Path to daemon-policies.json
289
+ * @returns {object} Valid parsed config
290
+ * @throws {Error} When the file is missing or invalid
291
+ */
292
+ function loadRequiredPolicyConfig(filePath) {
293
+ const detailed = readPolicyConfigDetailed(filePath);
294
+ if (detailed.status !== 'ok') {
295
+ policyCache.set(filePath, null);
296
+ const err = new Error(`Required policy config ${detailed.status}: ${detailed.error}`);
297
+ err.code = detailed.status === 'missing'
298
+ ? 'POLICY_CONFIG_MISSING'
299
+ : 'POLICY_CONFIG_INVALID';
300
+ throw err;
301
+ }
302
+ policyCache.set(filePath, detailed.config);
303
+ return detailed.config;
304
+ }
305
+ /**
306
+ * Helper: check if value is an array of strings
307
+ */
308
+ function isStringArray(v) {
309
+ return Array.isArray(v) && v.every((x) => typeof x === 'string');
310
+ }
311
+ /**
312
+ * Validate per-operation constraints. Returns { errors: string[] }.
313
+ * Constraint fields are validated based on operation type.
314
+ */
315
+ function validateOpConstraints(opName, constraints) {
316
+ const errors = [];
317
+ // transfer
318
+ if (opName === 'transfer') {
319
+ if (constraints.allowedToAccounts !== undefined && !isStringArray(constraints.allowedToAccounts))
320
+ errors.push('allowedToAccounts must be an array of strings');
321
+ if (constraints.allowedAssets !== undefined && !isStringArray(constraints.allowedAssets))
322
+ errors.push('allowedAssets must be an array of strings');
323
+ if (constraints.maxAmount !== undefined && !isPositiveInt(constraints.maxAmount))
324
+ errors.push('maxAmount must be a positive integer');
325
+ }
326
+ // Fields valid for limit_order_create and limit_order_update
327
+ if (['limit_order_create', 'limit_order_update'].includes(opName)) {
328
+ if (constraints.allowedSellAssets !== undefined) {
329
+ if (!isStringArray(constraints.allowedSellAssets))
330
+ errors.push('allowedSellAssets must be an array of strings');
331
+ }
332
+ if (constraints.allowedReceiveAssets !== undefined) {
333
+ if (!isStringArray(constraints.allowedReceiveAssets))
334
+ errors.push('allowedReceiveAssets must be an array of strings');
335
+ }
336
+ }
337
+ // maxSellAmount, maxReceiveAmount, allowFillOrKill — only for limit_order_create
338
+ if (opName === 'limit_order_create') {
339
+ if (constraints.maxSellAmount !== undefined && !isPositiveInt(constraints.maxSellAmount))
340
+ errors.push('maxSellAmount must be a positive integer');
341
+ if (constraints.maxReceiveAmount !== undefined && !isPositiveInt(constraints.maxReceiveAmount))
342
+ errors.push('maxReceiveAmount must be a positive integer');
343
+ if (constraints.allowFillOrKill !== undefined && typeof constraints.allowFillOrKill !== 'boolean')
344
+ errors.push('allowFillOrKill must be a boolean');
345
+ }
346
+ // maxDeltaSellAmount — only for limit_order_update
347
+ if (opName === 'limit_order_update') {
348
+ if (constraints.maxDeltaSellAmount !== undefined && !isPositiveInt(constraints.maxDeltaSellAmount))
349
+ errors.push('maxDeltaSellAmount must be a positive integer');
350
+ }
351
+ // call_order_update
352
+ if (opName === 'call_order_update') {
353
+ if (constraints.allowedAssets !== undefined && !isStringArray(constraints.allowedAssets))
354
+ errors.push('allowedAssets must be an array of strings');
355
+ if (constraints.collateralAsset !== undefined && typeof constraints.collateralAsset !== 'string')
356
+ errors.push('collateralAsset must be a string');
357
+ if (constraints.allowedCollateralAssets !== undefined && !isStringArray(constraints.allowedCollateralAssets))
358
+ errors.push('allowedCollateralAssets must be an array of strings');
359
+ if (constraints.maxDeltaCollateral !== undefined && !isPositiveInt(constraints.maxDeltaCollateral))
360
+ errors.push('maxDeltaCollateral must be a positive integer');
361
+ if (constraints.maxDeltaDebt !== undefined && !isPositiveInt(constraints.maxDeltaDebt))
362
+ errors.push('maxDeltaDebt must be a positive integer');
363
+ if (constraints.minCollateralRatio !== undefined && typeof constraints.minCollateralRatio !== 'number')
364
+ errors.push('minCollateralRatio must be a number');
365
+ if (constraints.maxCollateralRatio !== undefined && typeof constraints.maxCollateralRatio !== 'number')
366
+ errors.push('maxCollateralRatio must be a number');
367
+ if (constraints.targetCollateralRatio !== undefined && typeof constraints.targetCollateralRatio !== 'number')
368
+ errors.push('targetCollateralRatio must be a number');
369
+ }
370
+ // credit_offer_accept
371
+ if (opName === 'credit_offer_accept') {
372
+ if (constraints.allowedOfferIds !== undefined && !isStringArray(constraints.allowedOfferIds))
373
+ errors.push('allowedOfferIds must be an array of strings');
374
+ if (constraints.collateralAsset !== undefined && typeof constraints.collateralAsset !== 'string')
375
+ errors.push('collateralAsset must be a string');
376
+ if (constraints.allowedCollateralAssets !== undefined && !isStringArray(constraints.allowedCollateralAssets))
377
+ errors.push('allowedCollateralAssets must be an array of strings');
378
+ if (constraints.allowedDebtAssets !== undefined && !isStringArray(constraints.allowedDebtAssets))
379
+ errors.push('allowedDebtAssets must be an array of strings');
380
+ if (constraints.maxFeeRate !== undefined && !isPositiveInt(constraints.maxFeeRate))
381
+ errors.push('maxFeeRate must be a positive integer');
382
+ if (constraints.minDurationSeconds !== undefined && !isPositiveInt(constraints.minDurationSeconds))
383
+ errors.push('minDurationSeconds must be a positive integer');
384
+ }
385
+ // credit_deal_repay
386
+ if (opName === 'credit_deal_repay') {
387
+ if (constraints.disallowedDealIds !== undefined && !isStringArray(constraints.disallowedDealIds))
388
+ errors.push('disallowedDealIds must be an array of strings');
389
+ if (constraints.maxRepayAmount !== undefined && !isPositiveInt(constraints.maxRepayAmount))
390
+ errors.push('maxRepayAmount must be a positive integer');
391
+ if (constraints.maxCreditFee !== undefined && !isPositiveInt(constraints.maxCreditFee))
392
+ errors.push('maxCreditFee must be a positive integer');
393
+ }
394
+ // credit_deal_update
395
+ if (opName === 'credit_deal_update') {
396
+ if (constraints.disallowedDealIds !== undefined && !isStringArray(constraints.disallowedDealIds))
397
+ errors.push('disallowedDealIds must be an array of strings');
398
+ if (constraints.allowAutoRepay !== undefined && typeof constraints.allowAutoRepay !== 'boolean')
399
+ errors.push('allowAutoRepay must be a boolean');
400
+ }
401
+ // liquidity_pool_exchange
402
+ if (opName === 'liquidity_pool_exchange') {
403
+ if (constraints.allowedPools !== undefined && !isStringArray(constraints.allowedPools))
404
+ errors.push('allowedPools must be an array of strings');
405
+ if (constraints.allowedSellAssets !== undefined && !isStringArray(constraints.allowedSellAssets))
406
+ errors.push('allowedSellAssets must be an array of strings');
407
+ if (constraints.allowedReceiveAssets !== undefined && !isStringArray(constraints.allowedReceiveAssets))
408
+ errors.push('allowedReceiveAssets must be an array of strings');
409
+ if (constraints.maxSellAmount !== undefined && !isPositiveInt(constraints.maxSellAmount))
410
+ errors.push('maxSellAmount must be a positive integer');
411
+ }
412
+ // limit_order_cancel has no constraints
413
+ return { errors };
414
+ }
415
+ /**
416
+ * Validate raw policy config. Returns { valid: boolean, errors: string[] }.
417
+ */
418
+ function validatePolicyConfig(raw) {
419
+ const errors = [];
420
+ if (typeof raw !== 'object' || raw === null) {
421
+ errors.push('root must be an object');
422
+ return { valid: false, errors };
423
+ }
424
+ // sessionTtlMs: optional positive integer
425
+ if (raw.sessionTtlMs !== undefined) {
426
+ if (typeof raw.sessionTtlMs !== 'number' || raw.sessionTtlMs <= 0) {
427
+ errors.push('sessionTtlMs must be a positive integer');
428
+ }
429
+ }
430
+ // default: optional policy object
431
+ if (raw.default !== undefined) {
432
+ if (typeof raw.default !== 'object' || raw.default === null) {
433
+ errors.push('default must be an object');
434
+ }
435
+ else {
436
+ const { valid: validDefault, errors: defaultErrors } = validatePolicyObject(raw.default);
437
+ if (!validDefault) {
438
+ errors.push(`default: ${defaultErrors.join('; ')}`);
439
+ }
440
+ }
441
+ }
442
+ // accounts: optional object of policies
443
+ if (raw.accounts !== undefined) {
444
+ if (typeof raw.accounts !== 'object' || Array.isArray(raw.accounts)) {
445
+ errors.push('accounts must be an object');
446
+ }
447
+ else {
448
+ for (const [accountName, policy] of Object.entries(raw.accounts)) {
449
+ if (typeof policy !== 'object' || policy === null) {
450
+ errors.push(`accounts.${accountName} must be an object`);
451
+ }
452
+ else {
453
+ const { valid: validPolicy, errors: policyErrors } = validatePolicyObject(policy);
454
+ if (!validPolicy) {
455
+ errors.push(`accounts.${accountName}: ${policyErrors.join('; ')}`);
456
+ }
457
+ }
458
+ }
459
+ }
460
+ }
461
+ return { valid: errors.length === 0, errors };
462
+ }
463
+ /**
464
+ * Validate a single policy object (used by both default and per-account policies).
465
+ */
466
+ function validatePolicyObject(policy) {
467
+ const errors = [];
468
+ // allowedOpTypes: must be array of strings
469
+ if (policy.allowedOpTypes !== undefined) {
470
+ if (!Array.isArray(policy.allowedOpTypes)) {
471
+ errors.push('allowedOpTypes must be an array');
472
+ }
473
+ else if (!policy.allowedOpTypes.every((x) => typeof x === 'string')) {
474
+ errors.push('allowedOpTypes must be an array of strings');
475
+ }
476
+ }
477
+ // maxOpsPerBatch: must be positive integer
478
+ if (policy.maxOpsPerBatch !== undefined) {
479
+ if (typeof policy.maxOpsPerBatch !== 'number' || policy.maxOpsPerBatch <= 0) {
480
+ errors.push('maxOpsPerBatch must be a positive integer');
481
+ }
482
+ }
483
+ // allowedAssetIds: optional array of strings
484
+ if (policy.allowedAssetIds !== undefined) {
485
+ if (policy.allowedAssetIds !== null) {
486
+ if (!Array.isArray(policy.allowedAssetIds)) {
487
+ errors.push('allowedAssetIds must be an array or null');
488
+ }
489
+ else if (!policy.allowedAssetIds.every((x) => typeof x === 'string')) {
490
+ errors.push('allowedAssetIds must be an array of strings');
491
+ }
492
+ }
493
+ }
494
+ // executable: optional string path or null
495
+ if (policy.executable !== undefined) {
496
+ if (policy.executable !== null && typeof policy.executable !== 'string') {
497
+ errors.push('executable must be a string path or null');
498
+ }
499
+ }
500
+ // botHmacSecret: optional 64-char hex string (32 bytes)
501
+ if (policy.botHmacSecret !== undefined) {
502
+ if (typeof policy.botHmacSecret !== 'string' || !/^[0-9a-f]{64}$/i.test(policy.botHmacSecret)) {
503
+ errors.push('botHmacSecret must be a 64-char hex string (32 bytes)');
504
+ }
505
+ }
506
+ // allowedOps: optional object keyed by op_name → constraints (object or null)
507
+ if (policy.allowedOps !== undefined) {
508
+ if (policy.allowedOps !== null) {
509
+ if (typeof policy.allowedOps !== 'object' || Array.isArray(policy.allowedOps)) {
510
+ errors.push('allowedOps must be an object or null');
511
+ }
512
+ else {
513
+ for (const [opName, constraints] of Object.entries(policy.allowedOps)) {
514
+ if (constraints !== null) {
515
+ if (typeof constraints !== 'object' || Array.isArray(constraints)) {
516
+ errors.push(`allowedOps.${opName} must be an object or null`);
517
+ }
518
+ else {
519
+ const { errors: cErrors } = validateOpConstraints(opName, constraints);
520
+ for (const e of cErrors)
521
+ errors.push(`allowedOps.${opName}: ${e}`);
522
+ }
523
+ }
524
+ }
525
+ }
526
+ }
527
+ }
528
+ return { valid: errors.length === 0, errors };
529
+ }
530
+ /**
531
+ * Derive debt-policy constraints from profiles/bots.json for an account.
532
+ * Scans all bots using `accountName` as preferredAccount and extracts
533
+ * collateralAsset / asset mappings from debtPolicy.lending[].
534
+ *
535
+ * Returns { call_order_update?, credit_offer_accept?, credit_deal_repay? }
536
+ * where each op constraint may contain:
537
+ * - collateralAsset (string) — if all lending items for that op type share one collateral
538
+ * - allowedCollateralAssets (string[]) — if multiple collaterals are used
539
+ * - allowedDebtAssets (string[]) — debt assets used in credit lending items
540
+ */
541
+ function deriveDebtPolicyConstraints(accountName) {
542
+ if (!accountName)
543
+ return {};
544
+ try {
545
+ if (!storage.exists(BOTS_JSON_PATH))
546
+ return {};
547
+ const raw = storage.readFile(BOTS_JSON_PATH);
548
+ const parsed = parseJsonWithComments(raw);
549
+ const bots = Array.isArray(parsed)
550
+ ? parsed.filter(Boolean)
551
+ : (Array.isArray(parsed?.bots) ? parsed.bots.filter(Boolean) : []);
552
+ if (!Array.isArray(bots))
553
+ return {};
554
+ const mpaCollaterals = new Set();
555
+ const creditCollaterals = new Set();
556
+ const creditDebtAssets = new Set();
557
+ for (const bot of bots) {
558
+ if (!bot || bot.active === false)
559
+ continue;
560
+ const pref = bot.preferredAccount || bot.account;
561
+ if (pref !== accountName)
562
+ continue;
563
+ const dp = bot.debtPolicy;
564
+ if (!dp || !Array.isArray(dp.lending))
565
+ continue;
566
+ for (const item of dp.lending) {
567
+ if (!item || !item.asset || !item.collateralAsset)
568
+ continue;
569
+ if (item.type === 'mpa') {
570
+ mpaCollaterals.add(item.collateralAsset);
571
+ }
572
+ else if (item.type === 'creditOffer') {
573
+ creditCollaterals.add(item.collateralAsset);
574
+ creditDebtAssets.add(item.asset);
575
+ }
576
+ }
577
+ }
578
+ const constraints = {};
579
+ if (mpaCollaterals.size > 0) {
580
+ constraints.call_order_update = {};
581
+ if (mpaCollaterals.size === 1) {
582
+ constraints.call_order_update.collateralAsset = Array.from(mpaCollaterals)[0];
583
+ }
584
+ else {
585
+ constraints.call_order_update.allowedCollateralAssets = Array.from(mpaCollaterals);
586
+ }
587
+ }
588
+ if (creditCollaterals.size > 0 || creditDebtAssets.size > 0) {
589
+ constraints.credit_offer_accept = {};
590
+ if (creditCollaterals.size === 1) {
591
+ constraints.credit_offer_accept.collateralAsset = Array.from(creditCollaterals)[0];
592
+ }
593
+ else if (creditCollaterals.size > 1) {
594
+ constraints.credit_offer_accept.allowedCollateralAssets = Array.from(creditCollaterals);
595
+ }
596
+ if (creditDebtAssets.size > 0) {
597
+ constraints.credit_offer_accept.allowedDebtAssets = Array.from(creditDebtAssets);
598
+ }
599
+ }
600
+ if (creditDebtAssets.size > 0) {
601
+ constraints.credit_deal_repay = {
602
+ allowedDebtAssets: Array.from(creditDebtAssets),
603
+ };
604
+ }
605
+ return constraints;
606
+ }
607
+ catch {
608
+ return {};
609
+ }
610
+ }
611
+ /**
612
+ * Resolve the effective policy for an account by merging layers:
613
+ * builtin default → auto-derived debt constraints → config.default → config.accounts[accountName]
614
+ */
615
+ function resolveAccountPolicy(config, accountName) {
616
+ // Start with builtin
617
+ let policy = JSON.parse(JSON.stringify(BUILTIN_DEFAULT_POLICY));
618
+ // Layer auto-derived debt constraints from bots.json
619
+ const debtConstraints = deriveDebtPolicyConstraints(accountName);
620
+ if (Object.keys(debtConstraints).length > 0) {
621
+ policy.allowedOps = { ...policy.allowedOps };
622
+ for (const [opName, constraints] of Object.entries(debtConstraints)) {
623
+ policy.allowedOps[opName] = { ...(policy.allowedOps[opName] || {}), ...constraints };
624
+ }
625
+ }
626
+ // Layer on config.default
627
+ if (config && config.default) {
628
+ policy = { ...policy, ...config.default };
629
+ }
630
+ // Layer on config.accounts[accountName]
631
+ if (config && config.accounts && config.accounts[accountName]) {
632
+ policy = { ...policy, ...config.accounts[accountName] };
633
+ }
634
+ return policy;
635
+ }
636
+ /**
637
+ * Build the PolicyContext passed to evaluatePolicy and to executable hooks.
638
+ */
639
+ function buildPolicyContext(request) {
640
+ return {
641
+ accountName: request.accountName,
642
+ requestType: request.type,
643
+ sessionId: request.sessionId || null,
644
+ timestamp: new Date().toISOString(),
645
+ operations: request.operations || [],
646
+ };
647
+ }
648
+ /**
649
+ * Evaluate per-operation parameter constraints.
650
+ * Returns { allow: boolean, reason: string|null, policyId: string }
651
+ */
652
+ async function evaluateOpConstraints(opName, opData, constraints) {
653
+ if (!constraints)
654
+ return { allow: true, reason: null, policyId: null };
655
+ const d = opData || {};
656
+ if (opName === 'transfer') {
657
+ // allowedToAccounts
658
+ if (Array.isArray(constraints.allowedToAccounts) && constraints.allowedToAccounts.length > 0) {
659
+ if (!constraints.allowedToAccounts.includes(d.to)) {
660
+ return {
661
+ allow: false,
662
+ reason: `transfer: recipient "${d.to}" not in allowedToAccounts`,
663
+ policyId: 'opParams',
664
+ };
665
+ }
666
+ }
667
+ // allowedAssets
668
+ if (Array.isArray(constraints.allowedAssets) && constraints.allowedAssets.length > 0) {
669
+ const id = d.amount && d.amount.asset_id;
670
+ if (id && !constraints.allowedAssets.includes(id)) {
671
+ return {
672
+ allow: false,
673
+ reason: `transfer: asset "${id}" not in allowedAssets`,
674
+ policyId: 'opParams',
675
+ };
676
+ }
677
+ }
678
+ // maxAmount
679
+ if (constraints.maxAmount != null) {
680
+ const amt = d.amount && d.amount.amount;
681
+ if (typeof amt === 'number' && amt > constraints.maxAmount) {
682
+ return {
683
+ allow: false,
684
+ reason: `transfer: amount ${amt} exceeds maxAmount ${constraints.maxAmount}`,
685
+ policyId: 'opParams',
686
+ };
687
+ }
688
+ }
689
+ }
690
+ if (opName === 'limit_order_create') {
691
+ // allowedSellAssets
692
+ if (Array.isArray(constraints.allowedSellAssets) && constraints.allowedSellAssets.length > 0) {
693
+ const id = d.amount_to_sell && d.amount_to_sell.asset_id;
694
+ if (id && !constraints.allowedSellAssets.includes(id)) {
695
+ return {
696
+ allow: false,
697
+ reason: `limit_order_create: sell asset "${id}" not in allowedSellAssets`,
698
+ policyId: 'opParams',
699
+ };
700
+ }
701
+ }
702
+ // allowedReceiveAssets
703
+ if (Array.isArray(constraints.allowedReceiveAssets) && constraints.allowedReceiveAssets.length > 0) {
704
+ const id = d.min_to_receive && d.min_to_receive.asset_id;
705
+ if (id && !constraints.allowedReceiveAssets.includes(id)) {
706
+ return {
707
+ allow: false,
708
+ reason: `limit_order_create: receive asset "${id}" not in allowedReceiveAssets`,
709
+ policyId: 'opParams',
710
+ };
711
+ }
712
+ }
713
+ // maxSellAmount
714
+ if (constraints.maxSellAmount != null) {
715
+ const amt = d.amount_to_sell && d.amount_to_sell.amount;
716
+ if (typeof amt === 'number' && amt > constraints.maxSellAmount) {
717
+ return {
718
+ allow: false,
719
+ reason: `limit_order_create: sell amount ${amt} exceeds maxSellAmount ${constraints.maxSellAmount}`,
720
+ policyId: 'opParams',
721
+ };
722
+ }
723
+ }
724
+ // maxReceiveAmount
725
+ if (constraints.maxReceiveAmount != null) {
726
+ const amt = d.min_to_receive && d.min_to_receive.amount;
727
+ if (typeof amt === 'number' && amt > constraints.maxReceiveAmount) {
728
+ return {
729
+ allow: false,
730
+ reason: `limit_order_create: receive amount ${amt} exceeds maxReceiveAmount ${constraints.maxReceiveAmount}`,
731
+ policyId: 'opParams',
732
+ };
733
+ }
734
+ }
735
+ // allowFillOrKill
736
+ if (constraints.allowFillOrKill === false && d.fill_or_kill === true) {
737
+ return {
738
+ allow: false,
739
+ reason: 'limit_order_create: fill_or_kill=true not permitted',
740
+ policyId: 'opParams',
741
+ };
742
+ }
743
+ }
744
+ if (opName === 'limit_order_update') {
745
+ // allowedSellAssets via new_price.base
746
+ if (Array.isArray(constraints.allowedSellAssets) && constraints.allowedSellAssets.length > 0) {
747
+ const id = d.new_price && d.new_price.base && d.new_price.base.asset_id;
748
+ if (id && !constraints.allowedSellAssets.includes(id)) {
749
+ return {
750
+ allow: false,
751
+ reason: `limit_order_update: base asset "${id}" not in allowedSellAssets`,
752
+ policyId: 'opParams',
753
+ };
754
+ }
755
+ }
756
+ // allowedReceiveAssets via new_price.quote
757
+ if (Array.isArray(constraints.allowedReceiveAssets) && constraints.allowedReceiveAssets.length > 0) {
758
+ const id = d.new_price && d.new_price.quote && d.new_price.quote.asset_id;
759
+ if (id && !constraints.allowedReceiveAssets.includes(id)) {
760
+ return {
761
+ allow: false,
762
+ reason: `limit_order_update: quote asset "${id}" not in allowedReceiveAssets`,
763
+ policyId: 'opParams',
764
+ };
765
+ }
766
+ }
767
+ // maxDeltaSellAmount (abs value)
768
+ if (constraints.maxDeltaSellAmount != null) {
769
+ const delta = d.delta_amount_to_sell && d.delta_amount_to_sell.amount;
770
+ if (typeof delta === 'number' && Math.abs(delta) > constraints.maxDeltaSellAmount) {
771
+ return {
772
+ allow: false,
773
+ reason: `limit_order_update: |delta| ${Math.abs(delta)} exceeds maxDeltaSellAmount ${constraints.maxDeltaSellAmount}`,
774
+ policyId: 'opParams',
775
+ };
776
+ }
777
+ }
778
+ }
779
+ if (opName === 'call_order_update') {
780
+ // allowedAssets
781
+ if (Array.isArray(constraints.allowedAssets) && constraints.allowedAssets.length > 0) {
782
+ const collId = d.delta_collateral && d.delta_collateral.asset_id;
783
+ const debtId = d.delta_debt && d.delta_debt.asset_id;
784
+ if (collId && !constraints.allowedAssets.includes(collId)) {
785
+ return {
786
+ allow: false,
787
+ reason: `call_order_update: collateral asset "${collId}" not in allowedAssets`,
788
+ policyId: 'opParams',
789
+ };
790
+ }
791
+ if (debtId && !constraints.allowedAssets.includes(debtId)) {
792
+ return {
793
+ allow: false,
794
+ reason: `call_order_update: debt asset "${debtId}" not in allowedAssets`,
795
+ policyId: 'opParams',
796
+ };
797
+ }
798
+ }
799
+ if (constraints.collateralAsset) {
800
+ const collId = d.delta_collateral && d.delta_collateral.asset_id;
801
+ const resolved = await resolveConfiguredAssetRefs([constraints.collateralAsset], 'collateralAsset');
802
+ if (!resolved.ok) {
803
+ return {
804
+ allow: false,
805
+ reason: `call_order_update: ${resolved.reason}`,
806
+ policyId: 'opParams',
807
+ };
808
+ }
809
+ if (collId && !resolved.values.includes(String(collId))) {
810
+ return {
811
+ allow: false,
812
+ reason: `call_order_update: collateral asset "${collId}" does not match collateralAsset`,
813
+ policyId: 'opParams',
814
+ };
815
+ }
816
+ }
817
+ if (Array.isArray(constraints.allowedCollateralAssets) && constraints.allowedCollateralAssets.length > 0) {
818
+ const collId = d.delta_collateral && d.delta_collateral.asset_id;
819
+ const resolved = await resolveConfiguredAssetRefs(constraints.allowedCollateralAssets, 'allowedCollateralAssets');
820
+ if (!resolved.ok) {
821
+ return {
822
+ allow: false,
823
+ reason: `call_order_update: ${resolved.reason}`,
824
+ policyId: 'opParams',
825
+ };
826
+ }
827
+ if (collId && !resolved.values.includes(String(collId))) {
828
+ return {
829
+ allow: false,
830
+ reason: `call_order_update: collateral asset "${collId}" not in allowedCollateralAssets`,
831
+ policyId: 'opParams',
832
+ };
833
+ }
834
+ }
835
+ // maxDeltaCollateral
836
+ if (constraints.maxDeltaCollateral != null) {
837
+ const amt = d.delta_collateral && d.delta_collateral.amount;
838
+ if (typeof amt === 'number' && Math.abs(amt) > constraints.maxDeltaCollateral) {
839
+ return {
840
+ allow: false,
841
+ reason: `call_order_update: |delta_collateral| ${Math.abs(amt)} exceeds maxDeltaCollateral ${constraints.maxDeltaCollateral}`,
842
+ policyId: 'opParams',
843
+ };
844
+ }
845
+ }
846
+ // maxDeltaDebt
847
+ if (constraints.maxDeltaDebt != null) {
848
+ const amt = d.delta_debt && d.delta_debt.amount;
849
+ if (typeof amt === 'number' && Math.abs(amt) > constraints.maxDeltaDebt) {
850
+ return {
851
+ allow: false,
852
+ reason: `call_order_update: |delta_debt| ${Math.abs(amt)} exceeds maxDeltaDebt ${constraints.maxDeltaDebt}`,
853
+ policyId: 'opParams',
854
+ };
855
+ }
856
+ }
857
+ if (constraints.minCollateralRatio != null && d.extensions && d.extensions.target_collateral_ratio != null) {
858
+ const target = normalizeGrapheneCollateralRatio(d.extensions.target_collateral_ratio);
859
+ if (Number.isFinite(target) && target < constraints.minCollateralRatio) {
860
+ return {
861
+ allow: false,
862
+ reason: `call_order_update: target_collateral_ratio ${target} below minCollateralRatio ${constraints.minCollateralRatio}`,
863
+ policyId: 'opParams',
864
+ };
865
+ }
866
+ }
867
+ if (constraints.maxCollateralRatio != null && d.extensions && d.extensions.target_collateral_ratio != null) {
868
+ const target = normalizeGrapheneCollateralRatio(d.extensions.target_collateral_ratio);
869
+ if (Number.isFinite(target) && target > constraints.maxCollateralRatio) {
870
+ return {
871
+ allow: false,
872
+ reason: `call_order_update: target_collateral_ratio ${target} above maxCollateralRatio ${constraints.maxCollateralRatio}`,
873
+ policyId: 'opParams',
874
+ };
875
+ }
876
+ }
877
+ }
878
+ if (opName === 'credit_offer_accept') {
879
+ if (Array.isArray(constraints.allowedOfferIds) && constraints.allowedOfferIds.length > 0) {
880
+ const offerId = d.offer_id;
881
+ if (offerId && !constraints.allowedOfferIds.includes(String(offerId))) {
882
+ return {
883
+ allow: false,
884
+ reason: `credit_offer_accept: offer "${offerId}" not in allowedOfferIds`,
885
+ policyId: 'opParams',
886
+ };
887
+ }
888
+ }
889
+ if (constraints.collateralAsset) {
890
+ const assetId = d.collateral && d.collateral.asset_id;
891
+ const resolved = await resolveConfiguredAssetRefs([constraints.collateralAsset], 'collateralAsset');
892
+ if (!resolved.ok) {
893
+ return {
894
+ allow: false,
895
+ reason: `credit_offer_accept: ${resolved.reason}`,
896
+ policyId: 'opParams',
897
+ };
898
+ }
899
+ if (assetId && !resolved.values.includes(String(assetId))) {
900
+ return {
901
+ allow: false,
902
+ reason: `credit_offer_accept: collateral asset "${assetId}" does not match collateralAsset`,
903
+ policyId: 'opParams',
904
+ };
905
+ }
906
+ }
907
+ if (Array.isArray(constraints.allowedCollateralAssets) && constraints.allowedCollateralAssets.length > 0) {
908
+ const assetId = d.collateral && d.collateral.asset_id;
909
+ const resolved = await resolveConfiguredAssetRefs(constraints.allowedCollateralAssets, 'allowedCollateralAssets');
910
+ if (!resolved.ok) {
911
+ return {
912
+ allow: false,
913
+ reason: `credit_offer_accept: ${resolved.reason}`,
914
+ policyId: 'opParams',
915
+ };
916
+ }
917
+ if (assetId && !resolved.values.includes(String(assetId))) {
918
+ return {
919
+ allow: false,
920
+ reason: `credit_offer_accept: collateral asset "${assetId}" not in allowedCollateralAssets`,
921
+ policyId: 'opParams',
922
+ };
923
+ }
924
+ }
925
+ if (Array.isArray(constraints.allowedDebtAssets) && constraints.allowedDebtAssets.length > 0) {
926
+ const assetId = d.borrow_amount && d.borrow_amount.asset_id;
927
+ const resolved = await resolveConfiguredAssetRefs(constraints.allowedDebtAssets, 'allowedDebtAssets');
928
+ if (!resolved.ok) {
929
+ return {
930
+ allow: false,
931
+ reason: `credit_offer_accept: ${resolved.reason}`,
932
+ policyId: 'opParams',
933
+ };
934
+ }
935
+ if (assetId && !resolved.values.includes(String(assetId))) {
936
+ return {
937
+ allow: false,
938
+ reason: `credit_offer_accept: debt asset "${assetId}" not in allowedDebtAssets`,
939
+ policyId: 'opParams',
940
+ };
941
+ }
942
+ }
943
+ if (constraints.maxFeeRate != null) {
944
+ const maxFeeRate = Number(d.max_fee_rate);
945
+ if (Number.isFinite(maxFeeRate) && maxFeeRate > constraints.maxFeeRate) {
946
+ return {
947
+ allow: false,
948
+ reason: `credit_offer_accept: max_fee_rate ${maxFeeRate} exceeds maxFeeRate ${constraints.maxFeeRate}`,
949
+ policyId: 'opParams',
950
+ };
951
+ }
952
+ }
953
+ if (constraints.minDurationSeconds != null) {
954
+ const minDurationSeconds = Number(d.min_duration_seconds);
955
+ if (Number.isFinite(minDurationSeconds) && minDurationSeconds < constraints.minDurationSeconds) {
956
+ return {
957
+ allow: false,
958
+ reason: `credit_offer_accept: min_duration_seconds ${minDurationSeconds} below minDurationSeconds ${constraints.minDurationSeconds}`,
959
+ policyId: 'opParams',
960
+ };
961
+ }
962
+ }
963
+ }
964
+ if (opName === 'credit_deal_repay') {
965
+ if (Array.isArray(constraints.allowedDebtAssets) && constraints.allowedDebtAssets.length > 0) {
966
+ const assetId = d.repay_amount && d.repay_amount.asset_id;
967
+ const resolved = await resolveConfiguredAssetRefs(constraints.allowedDebtAssets, 'allowedDebtAssets');
968
+ if (!resolved.ok) {
969
+ return {
970
+ allow: false,
971
+ reason: `credit_deal_repay: ${resolved.reason}`,
972
+ policyId: 'opParams',
973
+ };
974
+ }
975
+ if (assetId && !resolved.values.includes(String(assetId))) {
976
+ return {
977
+ allow: false,
978
+ reason: `credit_deal_repay: debt asset "${assetId}" not in allowedDebtAssets`,
979
+ policyId: 'opParams',
980
+ };
981
+ }
982
+ }
983
+ if (constraints.maxRepayAmount != null) {
984
+ const amt = d.repay_amount && d.repay_amount.amount;
985
+ if (typeof amt === 'number' && amt > constraints.maxRepayAmount) {
986
+ return {
987
+ allow: false,
988
+ reason: `credit_deal_repay: repay amount ${amt} exceeds maxRepayAmount ${constraints.maxRepayAmount}`,
989
+ policyId: 'opParams',
990
+ };
991
+ }
992
+ }
993
+ if (constraints.maxCreditFee != null) {
994
+ const fee = d.credit_fee && d.credit_fee.amount;
995
+ if (typeof fee === 'number' && fee > constraints.maxCreditFee) {
996
+ return {
997
+ allow: false,
998
+ reason: `credit_deal_repay: credit fee ${fee} exceeds maxCreditFee ${constraints.maxCreditFee}`,
999
+ policyId: 'opParams',
1000
+ };
1001
+ }
1002
+ }
1003
+ }
1004
+ if (opName === 'credit_deal_update') {
1005
+ if (constraints.allowAutoRepay === false && d.auto_repay) {
1006
+ return {
1007
+ allow: false,
1008
+ reason: 'credit_deal_update: auto_repay change not permitted',
1009
+ policyId: 'opParams',
1010
+ };
1011
+ }
1012
+ }
1013
+ if (opName === 'liquidity_pool_exchange') {
1014
+ // allowedPools
1015
+ if (Array.isArray(constraints.allowedPools) && constraints.allowedPools.length > 0) {
1016
+ if (!constraints.allowedPools.includes(d.pool)) {
1017
+ return {
1018
+ allow: false,
1019
+ reason: `liquidity_pool_exchange: pool "${d.pool}" not in allowedPools`,
1020
+ policyId: 'opParams',
1021
+ };
1022
+ }
1023
+ }
1024
+ // allowedSellAssets
1025
+ if (Array.isArray(constraints.allowedSellAssets) && constraints.allowedSellAssets.length > 0) {
1026
+ const id = d.amount_to_sell && d.amount_to_sell.asset_id;
1027
+ if (id && !constraints.allowedSellAssets.includes(id)) {
1028
+ return {
1029
+ allow: false,
1030
+ reason: `liquidity_pool_exchange: sell asset "${id}" not in allowedSellAssets`,
1031
+ policyId: 'opParams',
1032
+ };
1033
+ }
1034
+ }
1035
+ // allowedReceiveAssets
1036
+ if (Array.isArray(constraints.allowedReceiveAssets) && constraints.allowedReceiveAssets.length > 0) {
1037
+ const id = d.min_to_receive && d.min_to_receive.asset_id;
1038
+ if (id && !constraints.allowedReceiveAssets.includes(id)) {
1039
+ return {
1040
+ allow: false,
1041
+ reason: `liquidity_pool_exchange: receive asset "${id}" not in allowedReceiveAssets`,
1042
+ policyId: 'opParams',
1043
+ };
1044
+ }
1045
+ }
1046
+ // maxSellAmount
1047
+ if (constraints.maxSellAmount != null) {
1048
+ const amt = d.amount_to_sell && d.amount_to_sell.amount;
1049
+ if (typeof amt === 'number' && amt > constraints.maxSellAmount) {
1050
+ return {
1051
+ allow: false,
1052
+ reason: `liquidity_pool_exchange: sell amount ${amt} exceeds maxSellAmount ${constraints.maxSellAmount}`,
1053
+ policyId: 'opParams',
1054
+ };
1055
+ }
1056
+ }
1057
+ }
1058
+ // limit_order_cancel — no constraints
1059
+ return { allow: true, reason: null, policyId: null };
1060
+ }
1061
+ /**
1062
+ * Evaluate a policy against a context. AND semantics: short-circuit on first denial.
1063
+ * Returns Promise<{ allow: boolean, reason: string|null, policyId: string|null }>
1064
+ */
1065
+ async function evaluatePolicy(policy, context) {
1066
+ try {
1067
+ // Step 1: allowedOps check (if present) or allowedOpTypes fallback
1068
+ if (policy.allowedOps && typeof policy.allowedOps === 'object') {
1069
+ for (const op of context.operations) {
1070
+ if (!op || typeof op !== 'object')
1071
+ continue;
1072
+ const opName = op.op_name;
1073
+ // Check if op type is allowed
1074
+ if (!(opName in policy.allowedOps)) {
1075
+ return {
1076
+ allow: false,
1077
+ reason: `op type "${opName}" not permitted`,
1078
+ policyId: 'allowedOps',
1079
+ };
1080
+ }
1081
+ // Get per-op constraints and evaluate
1082
+ const constraints = policy.allowedOps[opName];
1083
+ const result = await evaluateOpConstraints(opName, op.op_data, constraints);
1084
+ if (!result.allow) {
1085
+ return result;
1086
+ }
1087
+ }
1088
+ }
1089
+ else {
1090
+ // Fallback: allowedOpTypes check (backward compat)
1091
+ const allowed = policy.allowedOpTypes || [];
1092
+ if (Array.isArray(allowed) && allowed.length > 0) {
1093
+ for (const op of context.operations) {
1094
+ if (!op || typeof op !== 'object')
1095
+ continue;
1096
+ if (!allowed.includes(op.op_name)) {
1097
+ return {
1098
+ allow: false,
1099
+ reason: `op type "${op.op_name}" not permitted`,
1100
+ policyId: 'allowedOpTypes',
1101
+ };
1102
+ }
1103
+ }
1104
+ }
1105
+ }
1106
+ // Step 2: maxOpsPerBatch check
1107
+ {
1108
+ const max = policy.maxOpsPerBatch || 200;
1109
+ if (context.operations.length > max) {
1110
+ return {
1111
+ allow: false,
1112
+ reason: `batch size ${context.operations.length} exceeds maxOpsPerBatch ${max}`,
1113
+ policyId: 'maxOpsPerBatch',
1114
+ };
1115
+ }
1116
+ }
1117
+ // Step 3: allowedAssetIds check (optional)
1118
+ if (policy.allowedAssetIds && Array.isArray(policy.allowedAssetIds) && policy.allowedAssetIds.length > 0) {
1119
+ const allowed = policy.allowedAssetIds;
1120
+ for (const op of context.operations) {
1121
+ if (!op || typeof op !== 'object')
1122
+ continue;
1123
+ const opData = op.op_data || {};
1124
+ // Check amount_to_sell asset (for create/update)
1125
+ if (opData.amount_to_sell && opData.amount_to_sell.asset_id) {
1126
+ if (!allowed.includes(opData.amount_to_sell.asset_id)) {
1127
+ return {
1128
+ allow: false,
1129
+ reason: `asset_id "${opData.amount_to_sell.asset_id}" not in allowlist`,
1130
+ policyId: 'allowedAssetIds',
1131
+ };
1132
+ }
1133
+ }
1134
+ // Check min_to_receive asset (for create/update)
1135
+ if (opData.min_to_receive && opData.min_to_receive.asset_id) {
1136
+ if (!allowed.includes(opData.min_to_receive.asset_id)) {
1137
+ return {
1138
+ allow: false,
1139
+ reason: `asset_id "${opData.min_to_receive.asset_id}" not in allowlist`,
1140
+ policyId: 'allowedAssetIds',
1141
+ };
1142
+ }
1143
+ }
1144
+ if (op.op_name === 'call_order_update') {
1145
+ if (opData.delta_collateral && opData.delta_collateral.asset_id && !allowed.includes(opData.delta_collateral.asset_id)) {
1146
+ return {
1147
+ allow: false,
1148
+ reason: `asset_id "${opData.delta_collateral.asset_id}" not in allowlist`,
1149
+ policyId: 'allowedAssetIds',
1150
+ };
1151
+ }
1152
+ if (opData.delta_debt && opData.delta_debt.asset_id && !allowed.includes(opData.delta_debt.asset_id)) {
1153
+ return {
1154
+ allow: false,
1155
+ reason: `asset_id "${opData.delta_debt.asset_id}" not in allowlist`,
1156
+ policyId: 'allowedAssetIds',
1157
+ };
1158
+ }
1159
+ }
1160
+ if (op.op_name === 'credit_offer_accept') {
1161
+ if (opData.borrow_amount && opData.borrow_amount.asset_id && !allowed.includes(opData.borrow_amount.asset_id)) {
1162
+ return {
1163
+ allow: false,
1164
+ reason: `asset_id "${opData.borrow_amount.asset_id}" not in allowlist`,
1165
+ policyId: 'allowedAssetIds',
1166
+ };
1167
+ }
1168
+ if (opData.collateral && opData.collateral.asset_id && !allowed.includes(opData.collateral.asset_id)) {
1169
+ return {
1170
+ allow: false,
1171
+ reason: `asset_id "${opData.collateral.asset_id}" not in allowlist`,
1172
+ policyId: 'allowedAssetIds',
1173
+ };
1174
+ }
1175
+ }
1176
+ if (op.op_name === 'credit_deal_repay') {
1177
+ if (opData.repay_amount && opData.repay_amount.asset_id && !allowed.includes(opData.repay_amount.asset_id)) {
1178
+ return {
1179
+ allow: false,
1180
+ reason: `asset_id "${opData.repay_amount.asset_id}" not in allowlist`,
1181
+ policyId: 'allowedAssetIds',
1182
+ };
1183
+ }
1184
+ if (opData.credit_fee && opData.credit_fee.asset_id && !allowed.includes(opData.credit_fee.asset_id)) {
1185
+ return {
1186
+ allow: false,
1187
+ reason: `asset_id "${opData.credit_fee.asset_id}" not in allowlist`,
1188
+ policyId: 'allowedAssetIds',
1189
+ };
1190
+ }
1191
+ }
1192
+ }
1193
+ }
1194
+ // Step 4: executable check (optional)
1195
+ if (policy.executable && typeof policy.executable === 'string') {
1196
+ const result = await evaluateExecutable(policy.executable, context);
1197
+ if (!result.allow) {
1198
+ return {
1199
+ allow: false,
1200
+ reason: result.reason || 'denied by executable',
1201
+ policyId: 'executable',
1202
+ };
1203
+ }
1204
+ }
1205
+ // All checks passed
1206
+ return { allow: true, reason: null, policyId: null };
1207
+ }
1208
+ catch (error) {
1209
+ // Any evaluation error → deny
1210
+ return {
1211
+ allow: false,
1212
+ reason: `policy evaluation error: ${error.message}`,
1213
+ policyId: 'policy_eval_error',
1214
+ };
1215
+ }
1216
+ }
1217
+ /**
1218
+ * Spawn and evaluate a custom policy executable.
1219
+ * Executable receives PolicyContext JSON on stdin.
1220
+ * Must output { "allow": true/false, "reason": "..." } to stdout within 5 seconds.
1221
+ * Returns Promise<{ allow: boolean, reason: string|null }>
1222
+ */
1223
+ // File mode check: execute permission (X_OK = 1 on POSIX)
1224
+ const X_OK = 1;
1225
+ function evaluateExecutable(exePath, context) {
1226
+ return new Promise((resolve) => {
1227
+ let spawn;
1228
+ try {
1229
+ spawn = require('child_process').spawn;
1230
+ }
1231
+ catch {
1232
+ return resolve({ allow: false, reason: `executable not supported in this environment: ${exePath}` });
1233
+ }
1234
+ // Check file exists and is executable
1235
+ try {
1236
+ storage.access(exePath, X_OK);
1237
+ }
1238
+ catch {
1239
+ return resolve({ allow: false, reason: `executable not found or not executable: ${exePath}` });
1240
+ }
1241
+ let stdout = '';
1242
+ let stderr = '';
1243
+ const child = spawn(exePath, [], {
1244
+ stdio: ['pipe', 'pipe', 'pipe'],
1245
+ timeout: EXECUTABLE_TIMEOUT_MS,
1246
+ });
1247
+ child.stdout.on('data', (data) => {
1248
+ stdout += data.toString();
1249
+ });
1250
+ child.stderr.on('data', (data) => {
1251
+ stderr += data.toString();
1252
+ });
1253
+ child.on('error', (error) => {
1254
+ if (error.code === 'ETIMEDOUT') {
1255
+ resolve({ allow: false, reason: `executable timed out after ${EXECUTABLE_TIMEOUT_MS}ms` });
1256
+ }
1257
+ else {
1258
+ resolve({ allow: false, reason: `executable spawn failed: ${error.message}` });
1259
+ }
1260
+ });
1261
+ child.on('close', (code, signal) => {
1262
+ if (signal === 'SIGTERM') {
1263
+ return resolve({ allow: false, reason: `executable timed out after ${EXECUTABLE_TIMEOUT_MS}ms` });
1264
+ }
1265
+ if (code !== 0) {
1266
+ const stderrMsg = stderr.trim() ? `: ${stderr.trim()}` : '';
1267
+ return resolve({ allow: false, reason: `executable exited with code ${code}${stderrMsg}` });
1268
+ }
1269
+ // Parse JSON output
1270
+ try {
1271
+ const result = JSON.parse(stdout.trim());
1272
+ if (typeof result.allow !== 'boolean') {
1273
+ return resolve({ allow: false, reason: 'executable output missing "allow" field' });
1274
+ }
1275
+ resolve({
1276
+ allow: result.allow,
1277
+ reason: result.allow ? null : (result.reason || 'denied by executable'),
1278
+ });
1279
+ }
1280
+ catch (error) {
1281
+ resolve({ allow: false, reason: `executable output invalid JSON: ${error.message}` });
1282
+ }
1283
+ });
1284
+ // Send context to stdin
1285
+ try {
1286
+ child.stdin.write(JSON.stringify(context));
1287
+ child.stdin.end();
1288
+ }
1289
+ catch (error) {
1290
+ child.kill();
1291
+ resolve({ allow: false, reason: `failed to pipe context to executable: ${error.message}` });
1292
+ }
1293
+ });
1294
+ }
1295
+ /**
1296
+ * Load the botHmacSecret for an account from the policy config file.
1297
+ *
1298
+ * CONCURRENCY NOTE (M1): If two bot processes call this simultaneously for
1299
+ * the same account before either has written, both will generate independent
1300
+ * secrets. The second atomic rename clobbers the first, leaving both bots
1301
+ * holding the second bot's secret. The first bot's HMAC will then mismatch
1302
+ * until it retries (triggering another reload). This is a brief disruption
1303
+ * window, not a security breach — both bots are legitimate. If strict
1304
+ * per-bot isolation is required, use flock(2) on the policy file or switch
1305
+ * to a per-bot key-derivation from a shared master secret.
1306
+ *
1307
+ * @param {string} accountName - The account name
1308
+ * @param {string} policyConfigPath - Path to daemon-policies.json
1309
+ * @param {Object} [options] - Optional configuration
1310
+ * @returns {string|null} The botHmacSecret, or null if not configured
1311
+ */
1312
+ function loadBotHmacSecret(accountName, policyConfigPath, options = {}) {
1313
+ const quiet = options.quiet === true || options.silent === true;
1314
+ // Route through the module-scope policyLogger so output honours the
1315
+ // process-wide log level, file rotation, and PM2 auto-quiet rules.
1316
+ // `quiet` (per-call) suppresses routine info; security-relevant warns
1317
+ // and the auto-provision event still surface regardless.
1318
+ const info = (msg) => {
1319
+ if (!quiet)
1320
+ policyLogger.info(msg);
1321
+ };
1322
+ const debug = (msg) => {
1323
+ if (!quiet)
1324
+ policyLogger.debug?.(msg);
1325
+ };
1326
+ const warn = (msg) => {
1327
+ policyLogger.warn(msg);
1328
+ };
1329
+ // Always reload from disk to avoid serving a stale cached entry when
1330
+ // another process (or this process in an earlier call) already
1331
+ // auto-provisioned a new secret and signalled the daemon via SIGHUP.
1332
+ let config = loadPolicyConfig(policyConfigPath, { forceReload: true });
1333
+ if (!config)
1334
+ config = {};
1335
+ if (!config.accounts)
1336
+ config.accounts = {};
1337
+ if (!config.accounts[accountName])
1338
+ config.accounts[accountName] = {};
1339
+ let secret = config.accounts[accountName].botHmacSecret;
1340
+ if (!secret) {
1341
+ const newSecret = randomBytes(32).toString('hex');
1342
+ config.accounts[accountName].botHmacSecret = newSecret;
1343
+ // Atomic write via unified StorageAdapter.
1344
+ storage.writeJSON(policyConfigPath, config, { mode: 0o600, fsync: true });
1345
+ warn(`[policy] SECURITY: Auto-provisioned strict botHmacSecret for ${accountName} — first-time secret generation`);
1346
+ // Best-effort SIGHUP to the credential daemon so the new secret is
1347
+ // picked up immediately, without waiting for the fs.watch debounce
1348
+ // (500ms) or a SIGHUP from the operator. Three distinct failure
1349
+ // modes are handled separately:
1350
+ // - ready file missing: daemon is not running, nothing to do
1351
+ // - ready file empty: daemon is mid-startup; fs.watch will catch it
1352
+ // - ready file malformed (old format, partial write): warn and skip
1353
+ // - process.kill error (ESRCH=process gone, EPERM=not allowed):
1354
+ // warn — the fs.watch safety net will still pick up the change
1355
+ try {
1356
+ const readyFile = getCredentialReadyFilePath({ root: PATHS.PROJECT_ROOT });
1357
+ if (!storage.exists(readyFile)) {
1358
+ info(`[policy] Ready file ${readyFile} not present; daemon not running, SIGHUP skipped`);
1359
+ secret = newSecret;
1360
+ return secret;
1361
+ }
1362
+ const raw = storage.readFile(readyFile);
1363
+ if (!raw.trim()) {
1364
+ // File exists but is empty: daemon is mid-startup. Don't warn —
1365
+ // this is the expected race window between fork and ready-file write.
1366
+ // The fs.watch safety net will pick up the change within 500ms.
1367
+ debug(`[policy] Ready file ${readyFile} is empty (daemon mid-startup); fs.watch will pick up the change`);
1368
+ secret = newSecret;
1369
+ return secret;
1370
+ }
1371
+ const daemonInfo = JSON.parse(raw);
1372
+ if (daemonInfo && typeof daemonInfo.pid === 'number') {
1373
+ runtime.kill(daemonInfo.pid, 'SIGHUP');
1374
+ info(`[policy] Sent SIGHUP to credential daemon (pid ${daemonInfo.pid}) to activate new secret`);
1375
+ }
1376
+ else {
1377
+ warn(`[policy] Ready file ${readyFile} has no numeric pid field; skipping SIGHUP`);
1378
+ }
1379
+ }
1380
+ catch (e) {
1381
+ if (e && e.code === 'ENOENT') {
1382
+ info(`[policy] Ready file not present; daemon not running, SIGHUP skipped`);
1383
+ }
1384
+ else if (e instanceof SyntaxError) {
1385
+ warn(`[policy] Ready file is malformed JSON (${e.message}); SIGHUP skipped, fs.watch will pick up the change`);
1386
+ }
1387
+ else if (e && (e.code === 'ESRCH' || e.code === 'EPERM')) {
1388
+ warn(`[policy] SIGHUP to daemon failed (${e.code}: ${e.message}); fs.watch will pick up the change`);
1389
+ }
1390
+ else {
1391
+ warn(`[policy] Unexpected error signalling daemon (${e && e.message}); fs.watch will pick up the change`);
1392
+ }
1393
+ }
1394
+ secret = newSecret;
1395
+ }
1396
+ return secret;
1397
+ }
1398
+ /**
1399
+ * Verify that the signing request was HMAC-signed by the bot holding botHmacSecret.
1400
+ * Session binding: HMAC includes sessionId, so replay is impossible across sessions.
1401
+ *
1402
+ * @param {object} request - Parsed request: { accountName, sessionId, operations, hmac }
1403
+ * @param {object|null} policyConfig - Loaded daemon-policies.json content
1404
+ * @returns {{ valid: boolean, reason: string|null, skipped: boolean }}
1405
+ * skipped is always false — missing secrets are rejected in strict mode.
1406
+ */
1407
+ function verifySourceHmac(request, policyConfig) {
1408
+ const accountPolicy = policyConfig && policyConfig.accounts && policyConfig.accounts[request.accountName];
1409
+ const secretHex = accountPolicy && accountPolicy.botHmacSecret;
1410
+ // Strict Mode Enforcement: Reject instantly if no secret is configured
1411
+ if (!secretHex) {
1412
+ return { valid: false, reason: 'Strict Mode: botHmacSecret missing in daemon-policies.json', skipped: false };
1413
+ }
1414
+ const providedHmac = request.hmac;
1415
+ if (!providedHmac || typeof providedHmac !== 'string') {
1416
+ return { valid: false, reason: 'missing hmac field', skipped: false };
1417
+ }
1418
+ // Canonical signing payload: must match exactly what the bot computed
1419
+ const signingPayload = JSON.stringify({
1420
+ sessionId: request.sessionId,
1421
+ operations: request.operations,
1422
+ });
1423
+ const expected = createHmac('sha256', Buffer.from(secretHex, 'hex'))
1424
+ .update(signingPayload)
1425
+ .digest('hex');
1426
+ try {
1427
+ const valid = timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(providedHmac, 'hex'));
1428
+ return { valid, reason: valid ? null : 'hmac mismatch', skipped: false };
1429
+ }
1430
+ catch {
1431
+ // Buffer.from throws if provided hmac is not valid hex or wrong length
1432
+ return { valid: false, reason: 'invalid hmac format', skipped: false };
1433
+ }
1434
+ }
1435
+ module.exports = {
1436
+ POLICY_DENIED_PREFIX,
1437
+ BUILTIN_DEFAULT_POLICY,
1438
+ checkPolicyFileSecurity,
1439
+ ensurePolicyConfig,
1440
+ loadPolicyConfig,
1441
+ loadRequiredPolicyConfig,
1442
+ reloadPolicyFromDisk,
1443
+ validatePolicyConfig,
1444
+ deriveDebtPolicyConstraints,
1445
+ resolveAccountPolicy,
1446
+ buildPolicyContext,
1447
+ evaluatePolicy,
1448
+ verifySourceHmac,
1449
+ loadBotHmacSecret,
1450
+ setExternalAssetResolver,
1451
+ };
1452
+ //# sourceMappingURL=credential_policy.js.map