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.
- package/LICENSE +21 -0
- package/README.md +287 -0
- package/claw/README.md +513 -0
- package/claw/scripts/memu_runner.py +385 -0
- package/claw/skills/bitshares-guide/SKILL.md +14 -0
- package/claw/skills/bitshares-guide/references/example-skill-shells.md +18 -0
- package/claw/skills/bitshares-guide/references/presentation-patterns.md +19 -0
- package/claw/skills/bitshares-guide/references/scope-guardrails.md +9 -0
- package/claw/skills/launcher-ops/SKILL.md +18 -0
- package/claw/skills/launcher-ops/references/launcher-workflow.md +23 -0
- package/claw/skills/margin-trading/SKILL.md +23 -0
- package/claw/skills/margin-trading/references/honest-asset-list.md +74 -0
- package/claw/skills/margin-trading/references/honest-assets.md +44 -0
- package/claw/skills/margin-trading/references/position-management.md +203 -0
- package/claw/skills/margin-trading/references/trading-concepts.md +80 -0
- package/claw/skills/memu-memory/SKILL.md +218 -0
- package/claw/skills/shared/references/js-automation-overview.md +24 -0
- package/claw/skills/shared/references/safety-and-staleness.md +11 -0
- package/claw/skills/shared/references/skill-boundaries.md +17 -0
- package/claw/skills/trend-detection/SKILL.md +33 -0
- package/claw/skills/trend-detection/agents/openai.yaml +3 -0
- package/claw/skills/trend-detection/references/service.md +45 -0
- package/dist/analysis/ama_fitting/analyze_ama_price_changes.d.ts +3 -0
- package/dist/analysis/ama_fitting/analyze_ama_price_changes.d.ts.map +1 -0
- package/dist/analysis/ama_fitting/analyze_ama_price_changes.js +149 -0
- package/dist/analysis/ama_fitting/analyze_ama_price_changes.js.map +1 -0
- package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.d.ts +3 -0
- package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.d.ts.map +1 -0
- package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.js +387 -0
- package/dist/analysis/ama_fitting/analyze_lambda_vs_slow.js.map +1 -0
- package/dist/analysis/ama_fitting/calibrate_convergence_er.d.ts +3 -0
- package/dist/analysis/ama_fitting/calibrate_convergence_er.d.ts.map +1 -0
- package/dist/analysis/ama_fitting/calibrate_convergence_er.js +200 -0
- package/dist/analysis/ama_fitting/calibrate_convergence_er.js.map +1 -0
- package/dist/analysis/ama_fitting/fetch_lp_candles.d.ts +3 -0
- package/dist/analysis/ama_fitting/fetch_lp_candles.d.ts.map +1 -0
- package/dist/analysis/ama_fitting/fetch_lp_candles.js +212 -0
- package/dist/analysis/ama_fitting/fetch_lp_candles.js.map +1 -0
- package/dist/analysis/ama_fitting/generate_unified_comparison_chart.d.ts +31 -0
- package/dist/analysis/ama_fitting/generate_unified_comparison_chart.d.ts.map +1 -0
- package/dist/analysis/ama_fitting/generate_unified_comparison_chart.js +249 -0
- package/dist/analysis/ama_fitting/generate_unified_comparison_chart.js.map +1 -0
- package/dist/analysis/ama_fitting/optimizer_high_resolution.d.ts +2 -0
- package/dist/analysis/ama_fitting/optimizer_high_resolution.d.ts.map +1 -0
- package/dist/analysis/ama_fitting/optimizer_high_resolution.js +782 -0
- package/dist/analysis/ama_fitting/optimizer_high_resolution.js.map +1 -0
- package/dist/analysis/analyze_derivatives.d.ts +95 -0
- package/dist/analysis/analyze_derivatives.d.ts.map +1 -0
- package/dist/analysis/analyze_derivatives.js +295 -0
- package/dist/analysis/analyze_derivatives.js.map +1 -0
- package/dist/analysis/analyze_dynamic_weight.d.ts +14 -0
- package/dist/analysis/analyze_dynamic_weight.d.ts.map +1 -0
- package/dist/analysis/analyze_dynamic_weight.js +208 -0
- package/dist/analysis/analyze_dynamic_weight.js.map +1 -0
- package/dist/analysis/analyze_kalman.d.ts +13 -0
- package/dist/analysis/analyze_kalman.d.ts.map +1 -0
- package/dist/analysis/analyze_kalman.js +123 -0
- package/dist/analysis/analyze_kalman.js.map +1 -0
- package/dist/analysis/analyze_regime.d.ts +20 -0
- package/dist/analysis/analyze_regime.d.ts.map +1 -0
- package/dist/analysis/analyze_regime.js +139 -0
- package/dist/analysis/analyze_regime.js.map +1 -0
- package/dist/analysis/analyze_regime_windows.d.ts +19 -0
- package/dist/analysis/analyze_regime_windows.d.ts.map +1 -0
- package/dist/analysis/analyze_regime_windows.js +413 -0
- package/dist/analysis/analyze_regime_windows.js.map +1 -0
- package/dist/analysis/analyze_risk_profile.d.ts +3 -0
- package/dist/analysis/analyze_risk_profile.d.ts.map +1 -0
- package/dist/analysis/analyze_risk_profile.js +159 -0
- package/dist/analysis/analyze_risk_profile.js.map +1 -0
- package/dist/analysis/analyze_trade_heatmap.d.ts +3 -0
- package/dist/analysis/analyze_trade_heatmap.d.ts.map +1 -0
- package/dist/analysis/analyze_trade_heatmap.js +367 -0
- package/dist/analysis/analyze_trade_heatmap.js.map +1 -0
- package/dist/analysis/analyze_volatility.d.ts +22 -0
- package/dist/analysis/analyze_volatility.d.ts.map +1 -0
- package/dist/analysis/analyze_volatility.js +172 -0
- package/dist/analysis/analyze_volatility.js.map +1 -0
- package/dist/analysis/bot_fitting/backtest_ama_sweep.d.ts +99 -0
- package/dist/analysis/bot_fitting/backtest_ama_sweep.d.ts.map +1 -0
- package/dist/analysis/bot_fitting/backtest_ama_sweep.js +804 -0
- package/dist/analysis/bot_fitting/backtest_ama_sweep.js.map +1 -0
- package/dist/analysis/bot_fitting/backtest_bot_fitting.d.ts +2 -0
- package/dist/analysis/bot_fitting/backtest_bot_fitting.d.ts.map +1 -0
- package/dist/analysis/bot_fitting/backtest_bot_fitting.js +347 -0
- package/dist/analysis/bot_fitting/backtest_bot_fitting.js.map +1 -0
- package/dist/analysis/bot_fitting/shared_utils.d.ts +15 -0
- package/dist/analysis/bot_fitting/shared_utils.d.ts.map +1 -0
- package/dist/analysis/bot_fitting/shared_utils.js +48 -0
- package/dist/analysis/bot_fitting/shared_utils.js.map +1 -0
- package/dist/analysis/bot_key_utils.d.ts +16 -0
- package/dist/analysis/bot_key_utils.d.ts.map +1 -0
- package/dist/analysis/bot_key_utils.js +61 -0
- package/dist/analysis/bot_key_utils.js.map +1 -0
- package/dist/analysis/bot_usage/discover_bot_accounts.d.ts +3 -0
- package/dist/analysis/bot_usage/discover_bot_accounts.d.ts.map +1 -0
- package/dist/analysis/bot_usage/discover_bot_accounts.js +498 -0
- package/dist/analysis/bot_usage/discover_bot_accounts.js.map +1 -0
- package/dist/analysis/bot_usage/kibana_bot_queries.d.ts +546 -0
- package/dist/analysis/bot_usage/kibana_bot_queries.d.ts.map +1 -0
- package/dist/analysis/bot_usage/kibana_bot_queries.js +427 -0
- package/dist/analysis/bot_usage/kibana_bot_queries.js.map +1 -0
- package/dist/analysis/chart_utils.d.ts +13 -0
- package/dist/analysis/chart_utils.d.ts.map +1 -0
- package/dist/analysis/chart_utils.js +142 -0
- package/dist/analysis/chart_utils.js.map +1 -0
- package/dist/analysis/derivative_chart_generator.d.ts +18 -0
- package/dist/analysis/derivative_chart_generator.d.ts.map +1 -0
- package/dist/analysis/derivative_chart_generator.js +896 -0
- package/dist/analysis/derivative_chart_generator.js.map +1 -0
- package/dist/analysis/math_utils.d.ts +35 -0
- package/dist/analysis/math_utils.d.ts.map +1 -0
- package/dist/analysis/math_utils.js +121 -0
- package/dist/analysis/math_utils.js.map +1 -0
- package/dist/analysis/price_sources.d.ts +34 -0
- package/dist/analysis/price_sources.d.ts.map +1 -0
- package/dist/analysis/price_sources.js +103 -0
- package/dist/analysis/price_sources.js.map +1 -0
- package/dist/analysis/trade_profitability.d.ts +115 -0
- package/dist/analysis/trade_profitability.d.ts.map +1 -0
- package/dist/analysis/trade_profitability.js +1247 -0
- package/dist/analysis/trade_profitability.js.map +1 -0
- package/dist/analysis/tradingview/analyze_tradingview.d.ts +38 -0
- package/dist/analysis/tradingview/analyze_tradingview.d.ts.map +1 -0
- package/dist/analysis/tradingview/analyze_tradingview.js +212 -0
- package/dist/analysis/tradingview/analyze_tradingview.js.map +1 -0
- package/dist/analysis/tradingview/tradingview_uplot_chart_generator.d.ts +9 -0
- package/dist/analysis/tradingview/tradingview_uplot_chart_generator.d.ts.map +1 -0
- package/dist/analysis/tradingview/tradingview_uplot_chart_generator.js +1717 -0
- package/dist/analysis/tradingview/tradingview_uplot_chart_generator.js.map +1 -0
- package/dist/analysis/trend_detection/derivative_analyzer.d.ts +250 -0
- package/dist/analysis/trend_detection/derivative_analyzer.d.ts.map +1 -0
- package/dist/analysis/trend_detection/derivative_analyzer.js +903 -0
- package/dist/analysis/trend_detection/derivative_analyzer.js.map +1 -0
- package/dist/analysis/trend_detection/dynamic_weight_chart_generator.d.ts +6 -0
- package/dist/analysis/trend_detection/dynamic_weight_chart_generator.d.ts.map +1 -0
- package/dist/analysis/trend_detection/dynamic_weight_chart_generator.js +1449 -0
- package/dist/analysis/trend_detection/dynamic_weight_chart_generator.js.map +1 -0
- package/dist/analysis/trend_detection/hurst_analyzer.d.ts +42 -0
- package/dist/analysis/trend_detection/hurst_analyzer.d.ts.map +1 -0
- package/dist/analysis/trend_detection/hurst_analyzer.js +159 -0
- package/dist/analysis/trend_detection/hurst_analyzer.js.map +1 -0
- package/dist/analysis/trend_detection/kalman_chart_generator.d.ts +6 -0
- package/dist/analysis/trend_detection/kalman_chart_generator.d.ts.map +1 -0
- package/dist/analysis/trend_detection/kalman_chart_generator.js +408 -0
- package/dist/analysis/trend_detection/kalman_chart_generator.js.map +1 -0
- package/dist/analysis/trend_detection/kalman_trend_analyzer.d.ts +103 -0
- package/dist/analysis/trend_detection/kalman_trend_analyzer.d.ts.map +1 -0
- package/dist/analysis/trend_detection/kalman_trend_analyzer.js +229 -0
- package/dist/analysis/trend_detection/kalman_trend_analyzer.js.map +1 -0
- package/dist/analysis/trend_detection/kalman_velocity_smoothing.d.ts +34 -0
- package/dist/analysis/trend_detection/kalman_velocity_smoothing.d.ts.map +1 -0
- package/dist/analysis/trend_detection/kalman_velocity_smoothing.js +89 -0
- package/dist/analysis/trend_detection/kalman_velocity_smoothing.js.map +1 -0
- package/dist/analysis/trend_detection/permutation_entropy_analyzer.d.ts +39 -0
- package/dist/analysis/trend_detection/permutation_entropy_analyzer.d.ts.map +1 -0
- package/dist/analysis/trend_detection/permutation_entropy_analyzer.js +132 -0
- package/dist/analysis/trend_detection/permutation_entropy_analyzer.js.map +1 -0
- package/dist/analysis/trend_detection/regime_chart_generator.d.ts +6 -0
- package/dist/analysis/trend_detection/regime_chart_generator.d.ts.map +1 -0
- package/dist/analysis/trend_detection/regime_chart_generator.js +345 -0
- package/dist/analysis/trend_detection/regime_chart_generator.js.map +1 -0
- package/dist/analysis/trend_detection/tests/test_kalman_trend.d.ts +2 -0
- package/dist/analysis/trend_detection/tests/test_kalman_trend.d.ts.map +1 -0
- package/dist/analysis/trend_detection/tests/test_kalman_trend.js +130 -0
- package/dist/analysis/trend_detection/tests/test_kalman_trend.js.map +1 -0
- package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.d.ts +2 -0
- package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.d.ts.map +1 -0
- package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.js +38 -0
- package/dist/analysis/trend_detection/tests/test_kalman_velocity_smoothing.js.map +1 -0
- package/dist/analysis/trend_detection/volatility_chart_generator.d.ts +6 -0
- package/dist/analysis/trend_detection/volatility_chart_generator.d.ts.map +1 -0
- package/dist/analysis/trend_detection/volatility_chart_generator.js +732 -0
- package/dist/analysis/trend_detection/volatility_chart_generator.js.map +1 -0
- package/dist/bot.d.ts +49 -0
- package/dist/bot.d.ts.map +1 -0
- package/dist/bot.js +221 -0
- package/dist/bot.js.map +1 -0
- package/dist/credential-daemon.d.ts +64 -0
- package/dist/credential-daemon.d.ts.map +1 -0
- package/dist/credential-daemon.js +987 -0
- package/dist/credential-daemon.js.map +1 -0
- package/dist/dexbot.d.ts +87 -0
- package/dist/dexbot.d.ts.map +1 -0
- package/dist/dexbot.js +1222 -0
- package/dist/dexbot.js.map +1 -0
- package/dist/market_adapter/ama_signal_runner.d.ts +3 -0
- package/dist/market_adapter/ama_signal_runner.d.ts.map +1 -0
- package/dist/market_adapter/ama_signal_runner.js +175 -0
- package/dist/market_adapter/ama_signal_runner.js.map +1 -0
- package/dist/market_adapter/candle_utils.d.ts +57 -0
- package/dist/market_adapter/candle_utils.d.ts.map +1 -0
- package/dist/market_adapter/candle_utils.js +252 -0
- package/dist/market_adapter/candle_utils.js.map +1 -0
- package/dist/market_adapter/core/asymmetric_bounds.d.ts +20 -0
- package/dist/market_adapter/core/asymmetric_bounds.d.ts.map +1 -0
- package/dist/market_adapter/core/asymmetric_bounds.js +88 -0
- package/dist/market_adapter/core/asymmetric_bounds.js.map +1 -0
- package/dist/market_adapter/core/config_normalizers.d.ts +10 -0
- package/dist/market_adapter/core/config_normalizers.d.ts.map +1 -0
- package/dist/market_adapter/core/config_normalizers.js +24 -0
- package/dist/market_adapter/core/config_normalizers.js.map +1 -0
- package/dist/market_adapter/core/kibana_candles.d.ts +74 -0
- package/dist/market_adapter/core/kibana_candles.d.ts.map +1 -0
- package/dist/market_adapter/core/kibana_candles.js +249 -0
- package/dist/market_adapter/core/kibana_candles.js.map +1 -0
- package/dist/market_adapter/core/kibana_client.d.ts +27 -0
- package/dist/market_adapter/core/kibana_client.d.ts.map +1 -0
- package/dist/market_adapter/core/kibana_client.js +120 -0
- package/dist/market_adapter/core/kibana_client.js.map +1 -0
- package/dist/market_adapter/core/kibana_market_candles.d.ts +143 -0
- package/dist/market_adapter/core/kibana_market_candles.d.ts.map +1 -0
- package/dist/market_adapter/core/kibana_market_candles.js +170 -0
- package/dist/market_adapter/core/kibana_market_candles.js.map +1 -0
- package/dist/market_adapter/core/market_adapter_service.d.ts +210 -0
- package/dist/market_adapter/core/market_adapter_service.d.ts.map +1 -0
- package/dist/market_adapter/core/market_adapter_service.js +2328 -0
- package/dist/market_adapter/core/market_adapter_service.js.map +1 -0
- package/dist/market_adapter/core/strategies/ama.d.ts +2 -0
- package/dist/market_adapter/core/strategies/ama.d.ts.map +1 -0
- package/dist/market_adapter/core/strategies/ama.js +138 -0
- package/dist/market_adapter/core/strategies/ama.js.map +1 -0
- package/dist/market_adapter/core/strategies/ama_slope_model.d.ts +50 -0
- package/dist/market_adapter/core/strategies/ama_slope_model.d.ts.map +1 -0
- package/dist/market_adapter/core/strategies/ama_slope_model.js +143 -0
- package/dist/market_adapter/core/strategies/ama_slope_model.js.map +1 -0
- package/dist/market_adapter/core/strategies/atr/calculator.d.ts +12 -0
- package/dist/market_adapter/core/strategies/atr/calculator.d.ts.map +1 -0
- package/dist/market_adapter/core/strategies/atr/calculator.js +47 -0
- package/dist/market_adapter/core/strategies/atr/calculator.js.map +1 -0
- package/dist/market_adapter/core/strategies/collateral_manager.d.ts +32 -0
- package/dist/market_adapter/core/strategies/collateral_manager.d.ts.map +1 -0
- package/dist/market_adapter/core/strategies/collateral_manager.js +68 -0
- package/dist/market_adapter/core/strategies/collateral_manager.js.map +1 -0
- package/dist/market_adapter/core/strategies/regime_gate.d.ts +66 -0
- package/dist/market_adapter/core/strategies/regime_gate.d.ts.map +1 -0
- package/dist/market_adapter/core/strategies/regime_gate.js +189 -0
- package/dist/market_adapter/core/strategies/regime_gate.js.map +1 -0
- package/dist/market_adapter/index.d.ts +10 -0
- package/dist/market_adapter/index.d.ts.map +1 -0
- package/dist/market_adapter/index.js +71 -0
- package/dist/market_adapter/index.js.map +1 -0
- package/dist/market_adapter/inputs/fetch_cex_synthetic_data.d.ts +3 -0
- package/dist/market_adapter/inputs/fetch_cex_synthetic_data.d.ts.map +1 -0
- package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js +1165 -0
- package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js.map +1 -0
- package/dist/market_adapter/inputs/fetch_lp_data.d.ts +54 -0
- package/dist/market_adapter/inputs/fetch_lp_data.d.ts.map +1 -0
- package/dist/market_adapter/inputs/fetch_lp_data.js +743 -0
- package/dist/market_adapter/inputs/fetch_lp_data.js.map +1 -0
- package/dist/market_adapter/inputs/kibana_source.d.ts +68 -0
- package/dist/market_adapter/inputs/kibana_source.d.ts.map +1 -0
- package/dist/market_adapter/inputs/kibana_source.js +143 -0
- package/dist/market_adapter/inputs/kibana_source.js.map +1 -0
- package/dist/market_adapter/interval_utils.d.ts +6 -0
- package/dist/market_adapter/interval_utils.d.ts.map +1 -0
- package/dist/market_adapter/interval_utils.js +14 -0
- package/dist/market_adapter/interval_utils.js.map +1 -0
- package/dist/market_adapter/log_format.d.ts +16 -0
- package/dist/market_adapter/log_format.d.ts.map +1 -0
- package/dist/market_adapter/log_format.js +72 -0
- package/dist/market_adapter/log_format.js.map +1 -0
- package/dist/market_adapter/lp_chart_core.d.ts +6 -0
- package/dist/market_adapter/lp_chart_core.d.ts.map +1 -0
- package/dist/market_adapter/lp_chart_core.js +874 -0
- package/dist/market_adapter/lp_chart_core.js.map +1 -0
- package/dist/market_adapter/lp_chart_runner.d.ts +135 -0
- package/dist/market_adapter/lp_chart_runner.d.ts.map +1 -0
- package/dist/market_adapter/lp_chart_runner.js +337 -0
- package/dist/market_adapter/lp_chart_runner.js.map +1 -0
- package/dist/market_adapter/lp_chart_strategy_loader.d.ts +23 -0
- package/dist/market_adapter/lp_chart_strategy_loader.d.ts.map +1 -0
- package/dist/market_adapter/lp_chart_strategy_loader.js +169 -0
- package/dist/market_adapter/lp_chart_strategy_loader.js.map +1 -0
- package/dist/market_adapter/market_adapter.d.ts +133 -0
- package/dist/market_adapter/market_adapter.d.ts.map +1 -0
- package/dist/market_adapter/market_adapter.js +1331 -0
- package/dist/market_adapter/market_adapter.js.map +1 -0
- package/dist/market_adapter/merge_lp_data.d.ts +3 -0
- package/dist/market_adapter/merge_lp_data.d.ts.map +1 -0
- package/dist/market_adapter/merge_lp_data.js +125 -0
- package/dist/market_adapter/merge_lp_data.js.map +1 -0
- package/dist/market_adapter/test_helpers.d.ts +14 -0
- package/dist/market_adapter/test_helpers.d.ts.map +1 -0
- package/dist/market_adapter/test_helpers.js +22 -0
- package/dist/market_adapter/test_helpers.js.map +1 -0
- package/dist/market_adapter/utils/adapter_client.d.ts +20 -0
- package/dist/market_adapter/utils/adapter_client.d.ts.map +1 -0
- package/dist/market_adapter/utils/adapter_client.js +88 -0
- package/dist/market_adapter/utils/adapter_client.js.map +1 -0
- package/dist/market_adapter/utils/atomic_write.d.ts +9 -0
- package/dist/market_adapter/utils/atomic_write.d.ts.map +1 -0
- package/dist/market_adapter/utils/atomic_write.js +13 -0
- package/dist/market_adapter/utils/atomic_write.js.map +1 -0
- package/dist/market_adapter/utils/chain.d.ts +50 -0
- package/dist/market_adapter/utils/chain.d.ts.map +1 -0
- package/dist/market_adapter/utils/chain.js +196 -0
- package/dist/market_adapter/utils/chain.js.map +1 -0
- package/dist/market_adapter/utils/data_discovery.d.ts +6 -0
- package/dist/market_adapter/utils/data_discovery.d.ts.map +1 -0
- package/dist/market_adapter/utils/data_discovery.js +35 -0
- package/dist/market_adapter/utils/data_discovery.js.map +1 -0
- package/dist/market_adapter/utils/dynamic_grid_snapshot.d.ts +15 -0
- package/dist/market_adapter/utils/dynamic_grid_snapshot.d.ts.map +1 -0
- package/dist/market_adapter/utils/dynamic_grid_snapshot.js +60 -0
- package/dist/market_adapter/utils/dynamic_grid_snapshot.js.map +1 -0
- package/dist/market_adapter/utils/file_lock.d.ts +19 -0
- package/dist/market_adapter/utils/file_lock.d.ts.map +1 -0
- package/dist/market_adapter/utils/file_lock.js +191 -0
- package/dist/market_adapter/utils/file_lock.js.map +1 -0
- package/dist/market_adapter/utils/native_history.d.ts +19 -0
- package/dist/market_adapter/utils/native_history.d.ts.map +1 -0
- package/dist/market_adapter/utils/native_history.js +172 -0
- package/dist/market_adapter/utils/native_history.js.map +1 -0
- package/dist/market_adapter/utils/paths.d.ts +5 -0
- package/dist/market_adapter/utils/paths.d.ts.map +1 -0
- package/dist/market_adapter/utils/paths.js +7 -0
- package/dist/market_adapter/utils/paths.js.map +1 -0
- package/dist/modules/account_bots.d.ts +112 -0
- package/dist/modules/account_bots.d.ts.map +1 -0
- package/dist/modules/account_bots.js +1259 -0
- package/dist/modules/account_bots.js.map +1 -0
- package/dist/modules/account_orders.d.ts +273 -0
- package/dist/modules/account_orders.d.ts.map +1 -0
- package/dist/modules/account_orders.js +662 -0
- package/dist/modules/account_orders.js.map +1 -0
- package/dist/modules/authority_resolver.d.ts +2 -0
- package/dist/modules/authority_resolver.d.ts.map +1 -0
- package/dist/modules/authority_resolver.js +231 -0
- package/dist/modules/authority_resolver.js.map +1 -0
- package/dist/modules/bitshares-native/chain_client.d.ts +38 -0
- package/dist/modules/bitshares-native/chain_client.d.ts.map +1 -0
- package/dist/modules/bitshares-native/chain_client.js +322 -0
- package/dist/modules/bitshares-native/chain_client.js.map +1 -0
- package/dist/modules/bitshares-native/crypto/ecc.browser.d.ts +59 -0
- package/dist/modules/bitshares-native/crypto/ecc.browser.d.ts.map +1 -0
- package/dist/modules/bitshares-native/crypto/ecc.browser.js +456 -0
- package/dist/modules/bitshares-native/crypto/ecc.browser.js.map +1 -0
- package/dist/modules/bitshares-native/crypto/ecc.d.ts +66 -0
- package/dist/modules/bitshares-native/crypto/ecc.d.ts.map +1 -0
- package/dist/modules/bitshares-native/crypto/ecc.js +557 -0
- package/dist/modules/bitshares-native/crypto/ecc.js.map +1 -0
- package/dist/modules/bitshares-native/crypto/ecc_selector.d.ts +2 -0
- package/dist/modules/bitshares-native/crypto/ecc_selector.d.ts.map +1 -0
- package/dist/modules/bitshares-native/crypto/ecc_selector.js +20 -0
- package/dist/modules/bitshares-native/crypto/ecc_selector.js.map +1 -0
- package/dist/modules/bitshares-native/index.d.ts +3 -0
- package/dist/modules/bitshares-native/index.d.ts.map +1 -0
- package/dist/modules/bitshares-native/index.js +32 -0
- package/dist/modules/bitshares-native/index.js.map +1 -0
- package/dist/modules/bitshares-native/resolvers.d.ts +40 -0
- package/dist/modules/bitshares-native/resolvers.d.ts.map +1 -0
- package/dist/modules/bitshares-native/resolvers.js +161 -0
- package/dist/modules/bitshares-native/resolvers.js.map +1 -0
- package/dist/modules/bitshares-native/serial/chain_constants.d.ts +56 -0
- package/dist/modules/bitshares-native/serial/chain_constants.d.ts.map +1 -0
- package/dist/modules/bitshares-native/serial/chain_constants.js +92 -0
- package/dist/modules/bitshares-native/serial/chain_constants.js.map +1 -0
- package/dist/modules/bitshares-native/serial/index.d.ts +10 -0
- package/dist/modules/bitshares-native/serial/index.d.ts.map +1 -0
- package/dist/modules/bitshares-native/serial/index.js +14 -0
- package/dist/modules/bitshares-native/serial/index.js.map +1 -0
- package/dist/modules/bitshares-native/serial/operations.d.ts +102 -0
- package/dist/modules/bitshares-native/serial/operations.d.ts.map +1 -0
- package/dist/modules/bitshares-native/serial/operations.js +615 -0
- package/dist/modules/bitshares-native/serial/operations.js.map +1 -0
- package/dist/modules/bitshares-native/serial/serializer.d.ts +64 -0
- package/dist/modules/bitshares-native/serial/serializer.d.ts.map +1 -0
- package/dist/modules/bitshares-native/serial/serializer.js +252 -0
- package/dist/modules/bitshares-native/serial/serializer.js.map +1 -0
- package/dist/modules/bitshares-native/serial/types.d.ts +120 -0
- package/dist/modules/bitshares-native/serial/types.d.ts.map +1 -0
- package/dist/modules/bitshares-native/serial/types.js +837 -0
- package/dist/modules/bitshares-native/serial/types.js.map +1 -0
- package/dist/modules/bitshares-native/signing_client.d.ts +6 -0
- package/dist/modules/bitshares-native/signing_client.d.ts.map +1 -0
- package/dist/modules/bitshares-native/signing_client.js +141 -0
- package/dist/modules/bitshares-native/signing_client.js.map +1 -0
- package/dist/modules/bitshares-native/subscriptions.d.ts +6 -0
- package/dist/modules/bitshares-native/subscriptions.d.ts.map +1 -0
- package/dist/modules/bitshares-native/subscriptions.js +865 -0
- package/dist/modules/bitshares-native/subscriptions.js.map +1 -0
- package/dist/modules/bitshares-native/transport.d.ts +51 -0
- package/dist/modules/bitshares-native/transport.d.ts.map +1 -0
- package/dist/modules/bitshares-native/transport.js +447 -0
- package/dist/modules/bitshares-native/transport.js.map +1 -0
- package/dist/modules/bitshares-native/tx/builder.d.ts +30 -0
- package/dist/modules/bitshares-native/tx/builder.d.ts.map +1 -0
- package/dist/modules/bitshares-native/tx/builder.js +262 -0
- package/dist/modules/bitshares-native/tx/builder.js.map +1 -0
- package/dist/modules/bitshares_client.d.ts +129 -0
- package/dist/modules/bitshares_client.d.ts.map +1 -0
- package/dist/modules/bitshares_client.js +627 -0
- package/dist/modules/bitshares_client.js.map +1 -0
- package/dist/modules/bot_settings.d.ts +33 -0
- package/dist/modules/bot_settings.d.ts.map +1 -0
- package/dist/modules/bot_settings.js +328 -0
- package/dist/modules/bot_settings.js.map +1 -0
- package/dist/modules/bots_file_lock.d.ts +88 -0
- package/dist/modules/bots_file_lock.d.ts.map +1 -0
- package/dist/modules/bots_file_lock.js +161 -0
- package/dist/modules/bots_file_lock.js.map +1 -0
- package/dist/modules/chain_keys.d.ts +302 -0
- package/dist/modules/chain_keys.d.ts.map +1 -0
- package/dist/modules/chain_keys.js +1095 -0
- package/dist/modules/chain_keys.js.map +1 -0
- package/dist/modules/chain_orders.d.ts +423 -0
- package/dist/modules/chain_orders.d.ts.map +1 -0
- package/dist/modules/chain_orders.js +1201 -0
- package/dist/modules/chain_orders.js.map +1 -0
- package/dist/modules/cli_whitelist_args.d.ts +6 -0
- package/dist/modules/cli_whitelist_args.d.ts.map +1 -0
- package/dist/modules/cli_whitelist_args.js +13 -0
- package/dist/modules/cli_whitelist_args.js.map +1 -0
- package/dist/modules/config.d.ts +57 -0
- package/dist/modules/config.d.ts.map +1 -0
- package/dist/modules/config.js +107 -0
- package/dist/modules/config.js.map +1 -0
- package/dist/modules/constants.d.ts +635 -0
- package/dist/modules/constants.d.ts.map +1 -0
- package/dist/modules/constants.js +1464 -0
- package/dist/modules/constants.js.map +1 -0
- package/dist/modules/cr_planner.d.ts +51 -0
- package/dist/modules/cr_planner.d.ts.map +1 -0
- package/dist/modules/cr_planner.js +299 -0
- package/dist/modules/cr_planner.js.map +1 -0
- package/dist/modules/credential_policy.d.ts +188 -0
- package/dist/modules/credential_policy.d.ts.map +1 -0
- package/dist/modules/credential_policy.js +1452 -0
- package/dist/modules/credential_policy.js.map +1 -0
- package/dist/modules/credential_runtime.d.ts +42 -0
- package/dist/modules/credential_runtime.d.ts.map +1 -0
- package/dist/modules/credential_runtime.js +148 -0
- package/dist/modules/credential_runtime.js.map +1 -0
- package/dist/modules/credential_session_cache.d.ts +36 -0
- package/dist/modules/credential_session_cache.d.ts.map +1 -0
- package/dist/modules/credential_session_cache.js +106 -0
- package/dist/modules/credential_session_cache.js.map +1 -0
- package/dist/modules/credit_runtime.d.ts +412 -0
- package/dist/modules/credit_runtime.d.ts.map +1 -0
- package/dist/modules/credit_runtime.js +2866 -0
- package/dist/modules/credit_runtime.js.map +1 -0
- package/dist/modules/crypto/browser_provider.d.ts +15 -0
- package/dist/modules/crypto/browser_provider.d.ts.map +1 -0
- package/dist/modules/crypto/browser_provider.js +113 -0
- package/dist/modules/crypto/browser_provider.js.map +1 -0
- package/dist/modules/crypto/index.d.ts +9 -0
- package/dist/modules/crypto/index.d.ts.map +1 -0
- package/dist/modules/crypto/index.js +44 -0
- package/dist/modules/crypto/index.js.map +1 -0
- package/dist/modules/crypto/node_provider.d.ts +15 -0
- package/dist/modules/crypto/node_provider.d.ts.map +1 -0
- package/dist/modules/crypto/node_provider.js +74 -0
- package/dist/modules/crypto/node_provider.js.map +1 -0
- package/dist/modules/crypto/provider.d.ts +34 -0
- package/dist/modules/crypto/provider.d.ts.map +1 -0
- package/dist/modules/crypto/provider.js +3 -0
- package/dist/modules/crypto/provider.js.map +1 -0
- package/dist/modules/crypto/pure_ripemd160.d.ts +8 -0
- package/dist/modules/crypto/pure_ripemd160.d.ts.map +1 -0
- package/dist/modules/crypto/pure_ripemd160.js +142 -0
- package/dist/modules/crypto/pure_ripemd160.js.map +1 -0
- package/dist/modules/crypto/pure_scrypt.d.ts +23 -0
- package/dist/modules/crypto/pure_scrypt.d.ts.map +1 -0
- package/dist/modules/crypto/pure_scrypt.js +161 -0
- package/dist/modules/crypto/pure_scrypt.js.map +1 -0
- package/dist/modules/crypto/pure_secp256k1.d.ts +29 -0
- package/dist/modules/crypto/pure_secp256k1.d.ts.map +1 -0
- package/dist/modules/crypto/pure_secp256k1.js +195 -0
- package/dist/modules/crypto/pure_secp256k1.js.map +1 -0
- package/dist/modules/crypto/sync.d.ts +13 -0
- package/dist/modules/crypto/sync.d.ts.map +1 -0
- package/dist/modules/crypto/sync.js +37 -0
- package/dist/modules/crypto/sync.js.map +1 -0
- package/dist/modules/dexbot_class.d.ts +1074 -0
- package/dist/modules/dexbot_class.d.ts.map +1 -0
- package/dist/modules/dexbot_class.js +4613 -0
- package/dist/modules/dexbot_class.js.map +1 -0
- package/dist/modules/dexbot_credential_client.d.ts +71 -0
- package/dist/modules/dexbot_credential_client.d.ts.map +1 -0
- package/dist/modules/dexbot_credential_client.js +224 -0
- package/dist/modules/dexbot_credential_client.js.map +1 -0
- package/dist/modules/dexbot_fill_runtime.d.ts +173 -0
- package/dist/modules/dexbot_fill_runtime.d.ts.map +1 -0
- package/dist/modules/dexbot_fill_runtime.js +217 -0
- package/dist/modules/dexbot_fill_runtime.js.map +1 -0
- package/dist/modules/dexbot_maintenance_runtime.d.ts +279 -0
- package/dist/modules/dexbot_maintenance_runtime.d.ts.map +1 -0
- package/dist/modules/dexbot_maintenance_runtime.js +1613 -0
- package/dist/modules/dexbot_maintenance_runtime.js.map +1 -0
- package/dist/modules/env.d.ts +12 -0
- package/dist/modules/env.d.ts.map +1 -0
- package/dist/modules/env.js +57 -0
- package/dist/modules/env.js.map +1 -0
- package/dist/modules/fund_registry.d.ts +96 -0
- package/dist/modules/fund_registry.d.ts.map +1 -0
- package/dist/modules/fund_registry.js +261 -0
- package/dist/modules/fund_registry.js.map +1 -0
- package/dist/modules/general_settings.d.ts +36 -0
- package/dist/modules/general_settings.d.ts.map +1 -0
- package/dist/modules/general_settings.js +63 -0
- package/dist/modules/general_settings.js.map +1 -0
- package/dist/modules/graceful_shutdown.d.ts +86 -0
- package/dist/modules/graceful_shutdown.d.ts.map +1 -0
- package/dist/modules/graceful_shutdown.js +164 -0
- package/dist/modules/graceful_shutdown.js.map +1 -0
- package/dist/modules/key_store.d.ts +60 -0
- package/dist/modules/key_store.d.ts.map +1 -0
- package/dist/modules/key_store.js +215 -0
- package/dist/modules/key_store.js.map +1 -0
- package/dist/modules/launcher/bot_supervisor.d.ts +84 -0
- package/dist/modules/launcher/bot_supervisor.d.ts.map +1 -0
- package/dist/modules/launcher/bot_supervisor.js +1067 -0
- package/dist/modules/launcher/bot_supervisor.js.map +1 -0
- package/dist/modules/launcher/child_env.d.ts +9 -0
- package/dist/modules/launcher/child_env.d.ts.map +1 -0
- package/dist/modules/launcher/child_env.js +78 -0
- package/dist/modules/launcher/child_env.js.map +1 -0
- package/dist/modules/launcher/credential_bootstrap.d.ts +22 -0
- package/dist/modules/launcher/credential_bootstrap.d.ts.map +1 -0
- package/dist/modules/launcher/credential_bootstrap.js +303 -0
- package/dist/modules/launcher/credential_bootstrap.js.map +1 -0
- package/dist/modules/launcher/credential_daemon.d.ts +32 -0
- package/dist/modules/launcher/credential_daemon.d.ts.map +1 -0
- package/dist/modules/launcher/credential_daemon.js +173 -0
- package/dist/modules/launcher/credential_daemon.js.map +1 -0
- package/dist/modules/launcher/credential_secret.d.ts +6 -0
- package/dist/modules/launcher/credential_secret.d.ts.map +1 -0
- package/dist/modules/launcher/credential_secret.js +15 -0
- package/dist/modules/launcher/credential_secret.js.map +1 -0
- package/dist/modules/launcher/foreign_cred_daemon.d.ts +2 -0
- package/dist/modules/launcher/foreign_cred_daemon.d.ts.map +1 -0
- package/dist/modules/launcher/foreign_cred_daemon.js +166 -0
- package/dist/modules/launcher/foreign_cred_daemon.js.map +1 -0
- package/dist/modules/launcher/headless_password.d.ts +8 -0
- package/dist/modules/launcher/headless_password.d.ts.map +1 -0
- package/dist/modules/launcher/headless_password.js +33 -0
- package/dist/modules/launcher/headless_password.js.map +1 -0
- package/dist/modules/launcher/launch_modes.d.ts +36 -0
- package/dist/modules/launcher/launch_modes.d.ts.map +1 -0
- package/dist/modules/launcher/launch_modes.js +129 -0
- package/dist/modules/launcher/launch_modes.js.map +1 -0
- package/dist/modules/launcher/market_adapter_runtime.d.ts +43 -0
- package/dist/modules/launcher/market_adapter_runtime.d.ts.map +1 -0
- package/dist/modules/launcher/market_adapter_runtime.js +217 -0
- package/dist/modules/launcher/market_adapter_runtime.js.map +1 -0
- package/dist/modules/launcher/market_adapter_watchdog.d.ts +26 -0
- package/dist/modules/launcher/market_adapter_watchdog.d.ts.map +1 -0
- package/dist/modules/launcher/market_adapter_watchdog.js +214 -0
- package/dist/modules/launcher/market_adapter_watchdog.js.map +1 -0
- package/dist/modules/launcher/monolithic_runtime.d.ts +89 -0
- package/dist/modules/launcher/monolithic_runtime.d.ts.map +1 -0
- package/dist/modules/launcher/monolithic_runtime.js +425 -0
- package/dist/modules/launcher/monolithic_runtime.js.map +1 -0
- package/dist/modules/launcher/runtime_entry.d.ts +26 -0
- package/dist/modules/launcher/runtime_entry.d.ts.map +1 -0
- package/dist/modules/launcher/runtime_entry.js +49 -0
- package/dist/modules/launcher/runtime_entry.js.map +1 -0
- package/dist/modules/launcher/status_reporting.d.ts +48 -0
- package/dist/modules/launcher/status_reporting.d.ts.map +1 -0
- package/dist/modules/launcher/status_reporting.js +113 -0
- package/dist/modules/launcher/status_reporting.js.map +1 -0
- package/dist/modules/launcher/supervisor_control.d.ts +6 -0
- package/dist/modules/launcher/supervisor_control.d.ts.map +1 -0
- package/dist/modules/launcher/supervisor_control.js +59 -0
- package/dist/modules/launcher/supervisor_control.js.map +1 -0
- package/dist/modules/logger.d.ts +2 -0
- package/dist/modules/logger.d.ts.map +1 -0
- package/dist/modules/logger.js +71 -0
- package/dist/modules/logger.js.map +1 -0
- package/dist/modules/market_adapter_whitelist.d.ts +22 -0
- package/dist/modules/market_adapter_whitelist.d.ts.map +1 -0
- package/dist/modules/market_adapter_whitelist.js +82 -0
- package/dist/modules/market_adapter_whitelist.js.map +1 -0
- package/dist/modules/node_health_cache.d.ts +55 -0
- package/dist/modules/node_health_cache.d.ts.map +1 -0
- package/dist/modules/node_health_cache.js +134 -0
- package/dist/modules/node_health_cache.js.map +1 -0
- package/dist/modules/node_manager.d.ts +215 -0
- package/dist/modules/node_manager.d.ts.map +1 -0
- package/dist/modules/node_manager.js +628 -0
- package/dist/modules/node_manager.js.map +1 -0
- package/dist/modules/order/accounting.d.ts +349 -0
- package/dist/modules/order/accounting.d.ts.map +1 -0
- package/dist/modules/order/accounting.js +1191 -0
- package/dist/modules/order/accounting.js.map +1 -0
- package/dist/modules/order/async_lock.d.ts +126 -0
- package/dist/modules/order/async_lock.d.ts.map +1 -0
- package/dist/modules/order/async_lock.js +195 -0
- package/dist/modules/order/async_lock.js.map +1 -0
- package/dist/modules/order/export.d.ts +129 -0
- package/dist/modules/order/export.d.ts.map +1 -0
- package/dist/modules/order/export.js +316 -0
- package/dist/modules/order/export.js.map +1 -0
- package/dist/modules/order/format.d.ts +158 -0
- package/dist/modules/order/format.d.ts.map +1 -0
- package/dist/modules/order/format.js +232 -0
- package/dist/modules/order/format.js.map +1 -0
- package/dist/modules/order/grid.d.ts +549 -0
- package/dist/modules/order/grid.d.ts.map +1 -0
- package/dist/modules/order/grid.js +1746 -0
- package/dist/modules/order/grid.js.map +1 -0
- package/dist/modules/order/grid_reconcile.d.ts +154 -0
- package/dist/modules/order/grid_reconcile.d.ts.map +1 -0
- package/dist/modules/order/grid_reconcile.js +1192 -0
- package/dist/modules/order/grid_reconcile.js.map +1 -0
- package/dist/modules/order/index.d.ts +55 -0
- package/dist/modules/order/index.d.ts.map +1 -0
- package/dist/modules/order/index.js +79 -0
- package/dist/modules/order/index.js.map +1 -0
- package/dist/modules/order/logger.d.ts +136 -0
- package/dist/modules/order/logger.d.ts.map +1 -0
- package/dist/modules/order/logger.js +614 -0
- package/dist/modules/order/logger.js.map +1 -0
- package/dist/modules/order/logger_state.d.ts +133 -0
- package/dist/modules/order/logger_state.d.ts.map +1 -0
- package/dist/modules/order/logger_state.js +170 -0
- package/dist/modules/order/logger_state.js.map +1 -0
- package/dist/modules/order/manager.d.ts +413 -0
- package/dist/modules/order/manager.d.ts.map +1 -0
- package/dist/modules/order/manager.js +1605 -0
- package/dist/modules/order/manager.js.map +1 -0
- package/dist/modules/order/processed_fill_store.d.ts +135 -0
- package/dist/modules/order/processed_fill_store.d.ts.map +1 -0
- package/dist/modules/order/processed_fill_store.js +288 -0
- package/dist/modules/order/processed_fill_store.js.map +1 -0
- package/dist/modules/order/runner.d.ts +70 -0
- package/dist/modules/order/runner.d.ts.map +1 -0
- package/dist/modules/order/runner.js +140 -0
- package/dist/modules/order/runner.js.map +1 -0
- package/dist/modules/order/strategy.d.ts +196 -0
- package/dist/modules/order/strategy.d.ts.map +1 -0
- package/dist/modules/order/strategy.js +398 -0
- package/dist/modules/order/strategy.js.map +1 -0
- package/dist/modules/order/sync_engine.d.ts +386 -0
- package/dist/modules/order/sync_engine.d.ts.map +1 -0
- package/dist/modules/order/sync_engine.js +1459 -0
- package/dist/modules/order/sync_engine.js.map +1 -0
- package/dist/modules/order/utils/math.d.ts +677 -0
- package/dist/modules/order/utils/math.d.ts.map +1 -0
- package/dist/modules/order/utils/math.js +1172 -0
- package/dist/modules/order/utils/math.js.map +1 -0
- package/dist/modules/order/utils/order.d.ts +572 -0
- package/dist/modules/order/utils/order.d.ts.map +1 -0
- package/dist/modules/order/utils/order.js +1145 -0
- package/dist/modules/order/utils/order.js.map +1 -0
- package/dist/modules/order/utils/system.d.ts +268 -0
- package/dist/modules/order/utils/system.d.ts.map +1 -0
- package/dist/modules/order/utils/system.js +1261 -0
- package/dist/modules/order/utils/system.js.map +1 -0
- package/dist/modules/order/utils/validate.d.ts +280 -0
- package/dist/modules/order/utils/validate.d.ts.map +1 -0
- package/dist/modules/order/utils/validate.js +918 -0
- package/dist/modules/order/utils/validate.js.map +1 -0
- package/dist/modules/order/working_grid.d.ts +212 -0
- package/dist/modules/order/working_grid.d.ts.map +1 -0
- package/dist/modules/order/working_grid.js +279 -0
- package/dist/modules/order/working_grid.js.map +1 -0
- package/dist/modules/path_api.d.ts +32 -0
- package/dist/modules/path_api.d.ts.map +1 -0
- package/dist/modules/path_api.js +148 -0
- package/dist/modules/path_api.js.map +1 -0
- package/dist/modules/paths.d.ts +58 -0
- package/dist/modules/paths.d.ts.map +1 -0
- package/dist/modules/paths.js +82 -0
- package/dist/modules/paths.js.map +1 -0
- package/dist/modules/process_discovery.d.ts +58 -0
- package/dist/modules/process_discovery.d.ts.map +1 -0
- package/dist/modules/process_discovery.js +265 -0
- package/dist/modules/process_discovery.js.map +1 -0
- package/dist/modules/runtime.d.ts +34 -0
- package/dist/modules/runtime.d.ts.map +1 -0
- package/dist/modules/runtime.js +98 -0
- package/dist/modules/runtime.js.map +1 -0
- package/dist/modules/runtime_settings.d.ts +12 -0
- package/dist/modules/runtime_settings.d.ts.map +1 -0
- package/dist/modules/runtime_settings.js +122 -0
- package/dist/modules/runtime_settings.js.map +1 -0
- package/dist/modules/settings_merge.d.ts +38 -0
- package/dist/modules/settings_merge.d.ts.map +1 -0
- package/dist/modules/settings_merge.js +246 -0
- package/dist/modules/settings_merge.js.map +1 -0
- package/dist/modules/storage/browser_adapter.d.ts +56 -0
- package/dist/modules/storage/browser_adapter.d.ts.map +1 -0
- package/dist/modules/storage/browser_adapter.js +231 -0
- package/dist/modules/storage/browser_adapter.js.map +1 -0
- package/dist/modules/storage/index.d.ts +28 -0
- package/dist/modules/storage/index.d.ts.map +1 -0
- package/dist/modules/storage/index.js +52 -0
- package/dist/modules/storage/index.js.map +1 -0
- package/dist/modules/storage/node_adapter.d.ts +49 -0
- package/dist/modules/storage/node_adapter.d.ts.map +1 -0
- package/dist/modules/storage/node_adapter.js +167 -0
- package/dist/modules/storage/node_adapter.js.map +1 -0
- package/dist/modules/storage/types.d.ts +92 -0
- package/dist/modules/storage/types.d.ts.map +1 -0
- package/dist/modules/storage/types.js +3 -0
- package/dist/modules/storage/types.js.map +1 -0
- package/dist/modules/types.d.ts +1382 -0
- package/dist/modules/types.d.ts.map +1 -0
- package/dist/modules/types.js +11 -0
- package/dist/modules/types.js.map +1 -0
- package/dist/modules/utils/base58check.d.ts +12 -0
- package/dist/modules/utils/base58check.d.ts.map +1 -0
- package/dist/modules/utils/base58check.js +112 -0
- package/dist/modules/utils/base58check.js.map +1 -0
- package/dist/modules/utils/build_dir.d.ts +7 -0
- package/dist/modules/utils/build_dir.d.ts.map +1 -0
- package/dist/modules/utils/build_dir.js +8 -0
- package/dist/modules/utils/build_dir.js.map +1 -0
- package/dist/modules/utils/fs_utils.d.ts +25 -0
- package/dist/modules/utils/fs_utils.d.ts.map +1 -0
- package/dist/modules/utils/fs_utils.js +27 -0
- package/dist/modules/utils/fs_utils.js.map +1 -0
- package/dist/modules/utils/math_utils.d.ts +10 -0
- package/dist/modules/utils/math_utils.d.ts.map +1 -0
- package/dist/modules/utils/math_utils.js +17 -0
- package/dist/modules/utils/math_utils.js.map +1 -0
- package/dist/modules/validate_profiles.d.ts +37 -0
- package/dist/modules/validate_profiles.d.ts.map +1 -0
- package/dist/modules/validate_profiles.js +369 -0
- package/dist/modules/validate_profiles.js.map +1 -0
- package/dist/pm2.d.ts +167 -0
- package/dist/pm2.d.ts.map +1 -0
- package/dist/pm2.js +998 -0
- package/dist/pm2.js.map +1 -0
- package/dist/scripts/analyze-git.d.ts +11 -0
- package/dist/scripts/analyze-git.d.ts.map +1 -0
- package/dist/scripts/analyze-git.js +851 -0
- package/dist/scripts/analyze-git.js.map +1 -0
- package/dist/scripts/analyze-orders.d.ts +17 -0
- package/dist/scripts/analyze-orders.d.ts.map +1 -0
- package/dist/scripts/analyze-orders.js +1568 -0
- package/dist/scripts/analyze-orders.js.map +1 -0
- package/dist/scripts/diagnose-kibana-candles.d.ts +3 -0
- package/dist/scripts/diagnose-kibana-candles.d.ts.map +1 -0
- package/dist/scripts/diagnose-kibana-candles.js +82 -0
- package/dist/scripts/diagnose-kibana-candles.js.map +1 -0
- package/dist/scripts/diagnose-pool-history.d.ts +3 -0
- package/dist/scripts/diagnose-pool-history.d.ts.map +1 -0
- package/dist/scripts/diagnose-pool-history.js +296 -0
- package/dist/scripts/diagnose-pool-history.js.map +1 -0
- package/dist/scripts/divergence-calc.d.ts +26 -0
- package/dist/scripts/divergence-calc.d.ts.map +1 -0
- package/dist/scripts/divergence-calc.js +119 -0
- package/dist/scripts/divergence-calc.js.map +1 -0
- package/dist/scripts/generate_lp_chart.d.ts +31 -0
- package/dist/scripts/generate_lp_chart.d.ts.map +1 -0
- package/dist/scripts/generate_lp_chart.js +92 -0
- package/dist/scripts/generate_lp_chart.js.map +1 -0
- package/dist/scripts/generate_mainnet_corpus_report.d.ts +24 -0
- package/dist/scripts/generate_mainnet_corpus_report.d.ts.map +1 -0
- package/dist/scripts/generate_mainnet_corpus_report.js +237 -0
- package/dist/scripts/generate_mainnet_corpus_report.js.map +1 -0
- package/dist/scripts/generate_market_adapter_whitelist.d.ts +2 -0
- package/dist/scripts/generate_market_adapter_whitelist.d.ts.map +1 -0
- package/dist/scripts/generate_market_adapter_whitelist.js +111 -0
- package/dist/scripts/generate_market_adapter_whitelist.js.map +1 -0
- package/dist/scripts/migrate_bot_keys.d.ts +6 -0
- package/dist/scripts/migrate_bot_keys.d.ts.map +1 -0
- package/dist/scripts/migrate_bot_keys.js +301 -0
- package/dist/scripts/migrate_bot_keys.js.map +1 -0
- package/dist/scripts/native_release_gates.d.ts +3 -0
- package/dist/scripts/native_release_gates.d.ts.map +1 -0
- package/dist/scripts/native_release_gates.js +52 -0
- package/dist/scripts/native_release_gates.js.map +1 -0
- package/dist/scripts/print_grid.d.ts +16 -0
- package/dist/scripts/print_grid.d.ts.map +1 -0
- package/dist/scripts/print_grid.js +80 -0
- package/dist/scripts/print_grid.js.map +1 -0
- package/dist/scripts/run-tests.d.ts +2 -0
- package/dist/scripts/run-tests.d.ts.map +1 -0
- package/dist/scripts/run-tests.js +49 -0
- package/dist/scripts/run-tests.js.map +1 -0
- package/dist/scripts/sync-version.d.ts +14 -0
- package/dist/scripts/sync-version.d.ts.map +1 -0
- package/dist/scripts/sync-version.js +158 -0
- package/dist/scripts/sync-version.js.map +1 -0
- package/dist/scripts/test-credit-renewal.d.ts +2 -0
- package/dist/scripts/test-credit-renewal.d.ts.map +1 -0
- package/dist/scripts/test-credit-renewal.js +329 -0
- package/dist/scripts/test-credit-renewal.js.map +1 -0
- package/dist/scripts/update.d.ts +24 -0
- package/dist/scripts/update.d.ts.map +1 -0
- package/dist/scripts/update.js +650 -0
- package/dist/scripts/update.js.map +1 -0
- package/dist/scripts/validate_bots.d.ts +16 -0
- package/dist/scripts/validate_bots.d.ts.map +1 -0
- package/dist/scripts/validate_bots.js +106 -0
- package/dist/scripts/validate_bots.js.map +1 -0
- package/dist/scripts/verify-browser-bundle.d.ts +22 -0
- package/dist/scripts/verify-browser-bundle.d.ts.map +1 -0
- package/dist/scripts/verify-browser-bundle.js +339 -0
- package/dist/scripts/verify-browser-bundle.js.map +1 -0
- package/dist/unlock.d.ts +48 -0
- package/dist/unlock.d.ts.map +1 -0
- package/dist/unlock.js +925 -0
- package/dist/unlock.js.map +1 -0
- package/package.json +112 -0
- package/scripts/README.md +356 -0
- package/scripts/clear-all.sh +195 -0
- package/scripts/clear-logs.sh +95 -0
- package/scripts/clear-market-adapter.sh +196 -0
- package/scripts/clear-orders.sh +113 -0
- package/scripts/create-bot-symlinks.sh +51 -0
- package/scripts/postinstall.js +9 -0
- package/scripts/reset-settings.sh +118 -0
|
@@ -0,0 +1,1201 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* modules/chain_orders.ts - Blockchain Interaction Layer
|
|
4
|
+
*
|
|
5
|
+
* BitShares blockchain operations and order management interface.
|
|
6
|
+
* Provides all blockchain I/O operations for the bot.
|
|
7
|
+
*
|
|
8
|
+
* Responsibilities:
|
|
9
|
+
* - Account selection and management
|
|
10
|
+
* - Reading open orders from blockchain
|
|
11
|
+
* - Creating, updating, and canceling limit orders
|
|
12
|
+
* - Listening for fill events via subscriptions
|
|
13
|
+
* - Fetching on-chain asset balances and metadata
|
|
14
|
+
* - Batch operation execution
|
|
15
|
+
* - Fill deduplication and processing mode selection
|
|
16
|
+
*
|
|
17
|
+
* All order amounts are human-readable floats externally,
|
|
18
|
+
* converted to blockchain integers internally using asset precision.
|
|
19
|
+
*
|
|
20
|
+
* ===============================================================================
|
|
21
|
+
* EXPORTS (18 functions + 2 constants)
|
|
22
|
+
* ===============================================================================
|
|
23
|
+
*
|
|
24
|
+
* ACCOUNT MANAGEMENT (3 functions - async)
|
|
25
|
+
* 1. selectAccount(nameOrId) - Select/authenticate account by name or ID
|
|
26
|
+
* Prompts for password if needed, caches selection
|
|
27
|
+
* Returns { accountId, accountName, authority }
|
|
28
|
+
*
|
|
29
|
+
* 2. setPreferredAccount(accountId, accountName) - Set preferred account
|
|
30
|
+
* Used by selectAccount() if no account specified
|
|
31
|
+
*
|
|
32
|
+
* 3. resolveAccountId(nameOrId) - Resolve account name to ID (async, cached)
|
|
33
|
+
* 4. resolveAccountName(id) - Resolve account ID to name (async, cached)
|
|
34
|
+
*
|
|
35
|
+
* ORDER OPERATIONS (5 functions - async)
|
|
36
|
+
* 5. readOpenOrders(accountId) - Read all open orders for account
|
|
37
|
+
* Returns array of { id, seller, sells, receives, ...blockchain fields }
|
|
38
|
+
*
|
|
39
|
+
* 6. createOrder(accountId, orderParams, broadcastFn) - Create limit order
|
|
40
|
+
* orderParams: { sellSymbol, sellAmount, buySymbol, buyAmount, fillOrKill, ... }
|
|
41
|
+
* Returns { tx_id, operation_results } or throws
|
|
42
|
+
*
|
|
43
|
+
* 7. updateOrder(accountId, orderId, newAmount, broadcastFn) - Update existing order
|
|
44
|
+
* Changes order amount, preserves price
|
|
45
|
+
* Returns transaction result
|
|
46
|
+
*
|
|
47
|
+
* 8. cancelOrder(accountId, orderId, broadcastFn) - Cancel order
|
|
48
|
+
* Removes order from blockchain
|
|
49
|
+
* Returns transaction result
|
|
50
|
+
*
|
|
51
|
+
* 9. executeBatch(operations, broadcastFn) - Execute batch of operations
|
|
52
|
+
* Executes multiple operations (create/update/cancel) in one transaction
|
|
53
|
+
* Returns transaction result
|
|
54
|
+
*
|
|
55
|
+
* FILL EVENT HANDLING (1 function - async)
|
|
56
|
+
* 10. listenForFills(accountId, fillCallback) - Subscribe to fill events
|
|
57
|
+
* Invokes fillCallback({ id, orderId, side, amount, price, proceeds, ... })
|
|
58
|
+
* Returns unsubscribe function
|
|
59
|
+
*
|
|
60
|
+
* ACCOUNT STATE (1 function - async)
|
|
61
|
+
* 11. getOnChainAssetBalances(accountId) - Fetch account asset balances
|
|
62
|
+
* Returns { BTS: amount, USD: amount, ... } (human-readable floats)
|
|
63
|
+
*
|
|
64
|
+
* OPERATION BUILDERS (3 functions)
|
|
65
|
+
* 12. buildCreateOrderOp(accountId, orderParams) - Build create order operation
|
|
66
|
+
* 13. buildUpdateOrderOp(accountId, orderId, newAmount) - Build update order operation
|
|
67
|
+
* 14. buildCancelOrderOp(accountId, orderId) - Build cancel order operation
|
|
68
|
+
*
|
|
69
|
+
* CONFIGURATION (2 functions/constants)
|
|
70
|
+
* 15. getFillProcessingMode() - Get current fill processing mode
|
|
71
|
+
* Returns 'history' (use fill event data) or 'open' (fetch open orders)
|
|
72
|
+
*
|
|
73
|
+
* 14. FILL_PROCESSING_MODE - Constant: current fill processing mode
|
|
74
|
+
*
|
|
75
|
+
* ===============================================================================
|
|
76
|
+
*
|
|
77
|
+
* ACCOUNT RESOLUTION:
|
|
78
|
+
* - Caches account name ↔ ID mappings to avoid repeated blockchain queries
|
|
79
|
+
* - Shared with modules/chain_keys.ts for authentication
|
|
80
|
+
*
|
|
81
|
+
* FILL MODES:
|
|
82
|
+
* - 'history' mode: Use fill event data directly (faster, preferred)
|
|
83
|
+
* - 'open' mode: Fetch open orders from blockchain (backup method, more API calls)
|
|
84
|
+
*
|
|
85
|
+
* RACE CONDITION PREVENTION:
|
|
86
|
+
* - _subscriptionLock: Serializes subscription map access
|
|
87
|
+
* - _preferredAccountLock: Serializes preferred account access
|
|
88
|
+
* - _resolutionLock: Serializes account resolution calls
|
|
89
|
+
*
|
|
90
|
+
* AUTHENTICATION:
|
|
91
|
+
* Moved to modules/chain_keys.ts for centralized key management.
|
|
92
|
+
* Use chain_keys.authenticate() and getPrivateKey() for auth operations.
|
|
93
|
+
*
|
|
94
|
+
* ===============================================================================
|
|
95
|
+
*/
|
|
96
|
+
const { BitShares, createAccountClient, waitForConnected, withTimeout } = require('./bitshares_client');
|
|
97
|
+
const { floatToBlockchainInt, blockchainToFloat, normalizeInt, validateOrderAmountsWithinLimits } = require('./order/utils/math');
|
|
98
|
+
const { FILL_PROCESSING, TIMING, NATIVE_CLIENT } = require('./constants');
|
|
99
|
+
const Format = require('./order/format');
|
|
100
|
+
const { toFiniteNumber } = Format;
|
|
101
|
+
const AsyncLock = require('./order/async_lock');
|
|
102
|
+
const { readInput } = require('./order/utils/system');
|
|
103
|
+
const chainKeys = require('./chain_keys');
|
|
104
|
+
const { getKeyStore } = require('./key_store');
|
|
105
|
+
const { BroadcastUncertainError } = require('./dexbot_credential_client');
|
|
106
|
+
const Logger = require('./logger');
|
|
107
|
+
const chainOrdersLogger = new Logger('ChainOrders');
|
|
108
|
+
const { ORDER_EVENTS } = NATIVE_CLIENT;
|
|
109
|
+
// Ring buffer of order ids the local process just cancelled.
|
|
110
|
+
// Used by the fill consumer to ignore a fill/cancel-history entry that is
|
|
111
|
+
// really just the propagation of the bot's own broadcast cancel op. Entries
|
|
112
|
+
// expire after RECENT_OWN_CANCEL_TTL_MS so the buffer self-cleans.
|
|
113
|
+
const RECENT_OWN_CANCEL_TTL_MS = ORDER_EVENTS.RECENT_OWN_CANCEL_TTL_MS;
|
|
114
|
+
const RECENT_OWN_CANCEL_MAX_ENTRIES = ORDER_EVENTS.RECENT_OWN_CANCEL_MAX_ENTRIES;
|
|
115
|
+
const _recentOwnCancels = new Map();
|
|
116
|
+
function recordOwnCancel(orderId) {
|
|
117
|
+
if (!orderId)
|
|
118
|
+
return;
|
|
119
|
+
const now = Date.now();
|
|
120
|
+
_recentOwnCancels.set(String(orderId), now);
|
|
121
|
+
// Lazy GC: drop expired entries when the buffer grows.
|
|
122
|
+
if (_recentOwnCancels.size > RECENT_OWN_CANCEL_MAX_ENTRIES) {
|
|
123
|
+
for (const [id, ts] of _recentOwnCancels) {
|
|
124
|
+
if (now - ts > RECENT_OWN_CANCEL_TTL_MS)
|
|
125
|
+
_recentOwnCancels.delete(id);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function recordOwnCancelOps(operations) {
|
|
130
|
+
for (const op of operations || []) {
|
|
131
|
+
if (op?.op_name === 'limit_order_cancel' && op.op_data?.order) {
|
|
132
|
+
recordOwnCancel(op.op_data.order);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function wasRecentlyOwnCancelled(orderId) {
|
|
137
|
+
if (!orderId)
|
|
138
|
+
return false;
|
|
139
|
+
const ts = _recentOwnCancels.get(String(orderId));
|
|
140
|
+
if (ts == null)
|
|
141
|
+
return false;
|
|
142
|
+
if (Date.now() - ts > RECENT_OWN_CANCEL_TTL_MS) {
|
|
143
|
+
_recentOwnCancels.delete(String(orderId));
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
// Key/auth helpers provided by modules/chain_keys.ts
|
|
149
|
+
// (authenticate(), getPrivateKey(), MasterPasswordError)
|
|
150
|
+
/**
|
|
151
|
+
* Fill processing mode from FILL_PROCESSING.MODE constant:
|
|
152
|
+
* - 'history': Use fill event data directly to match order_id with account_orders (preferred, faster)
|
|
153
|
+
* - 'open': Fetch open orders from blockchain and sync (backup method, more API calls)
|
|
154
|
+
*/
|
|
155
|
+
const FILL_PROCESSING_MODE = FILL_PROCESSING.MODE;
|
|
156
|
+
// AsyncLock instances for preventing race conditions
|
|
157
|
+
// _subscriptionLock: Serializes access to accountSubscriptions map
|
|
158
|
+
// _preferredAccountLock: Serializes access to preferredAccount global state
|
|
159
|
+
// _resolutionLock: Serializes account resolution calls and caching
|
|
160
|
+
const _subscriptionLock = new AsyncLock();
|
|
161
|
+
const _preferredAccountLock = new AsyncLock();
|
|
162
|
+
const _resolutionLock = new AsyncLock();
|
|
163
|
+
// Cache for account resolutions (name -> id and id -> name)
|
|
164
|
+
const _accountResolutionCache = new Map();
|
|
165
|
+
/**
|
|
166
|
+
* Resolve asset precision from ID or symbol via BitShares DB.
|
|
167
|
+
* @param {string} assetRef - Asset ID or symbol.
|
|
168
|
+
* @returns {Promise<number>} The asset's precision (number of decimals).
|
|
169
|
+
* @throws {Error} If precision cannot be resolved.
|
|
170
|
+
* @private
|
|
171
|
+
*/
|
|
172
|
+
async function _getAssetPrecision(assetRef) {
|
|
173
|
+
if (!assetRef)
|
|
174
|
+
throw new Error("Asset reference required for _getAssetPrecision");
|
|
175
|
+
try {
|
|
176
|
+
if (typeof assetRef === 'string' && assetRef.match(/^1\.3\.\d+$/)) {
|
|
177
|
+
if (BitShares && BitShares.db && typeof BitShares.db.get_assets === 'function') {
|
|
178
|
+
const assets = await BitShares.db.get_assets([assetRef]);
|
|
179
|
+
if (Array.isArray(assets) && assets[0] && typeof assets[0].precision === 'number')
|
|
180
|
+
return assets[0].precision;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
else if (typeof assetRef === 'string') {
|
|
184
|
+
if (BitShares && BitShares.db && typeof BitShares.db.lookup_asset_symbols === 'function') {
|
|
185
|
+
const res = await BitShares.db.lookup_asset_symbols([assetRef]);
|
|
186
|
+
if (Array.isArray(res) && res[0] && typeof res[0].precision === 'number')
|
|
187
|
+
return res[0].precision;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch (e) {
|
|
192
|
+
throw new Error(`CRITICAL: Could not resolve precision for asset ${assetRef}. Halting operation to prevent scaling errors. Cause: ${e.message}`);
|
|
193
|
+
}
|
|
194
|
+
throw new Error(`CRITICAL: Could not resolve precision for asset ${assetRef}. Halting operation to prevent scaling errors. Cause: asset not found or precision missing.`);
|
|
195
|
+
}
|
|
196
|
+
// Preferred account ID and name for operations (can be changed)
|
|
197
|
+
// Access MUST be protected by _preferredAccountLock to prevent race conditions
|
|
198
|
+
let preferredAccountId = null;
|
|
199
|
+
let preferredAccountName = null;
|
|
200
|
+
const _multiBotWarnings = new Set();
|
|
201
|
+
function _warnOnce(key, message) {
|
|
202
|
+
if (_multiBotWarnings.has(key))
|
|
203
|
+
return;
|
|
204
|
+
_multiBotWarnings.add(key);
|
|
205
|
+
chainOrdersLogger.warn(message);
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Set the preferred account for subsequent operations.
|
|
209
|
+
* This allows other functions to operate without requiring account parameters.
|
|
210
|
+
* Uses AsyncLock to prevent race conditions when multiple functions access this simultaneously.
|
|
211
|
+
* Warns once when overwriting a different account (multi-bot monolithic mode detection).
|
|
212
|
+
* @param {string} accountId - BitShares account ID (e.g., '1.2.12345')
|
|
213
|
+
* @param {string} accountName - Human-readable account name
|
|
214
|
+
*/
|
|
215
|
+
async function setPreferredAccount(accountId, accountName) {
|
|
216
|
+
await _preferredAccountLock.acquire(async () => {
|
|
217
|
+
if (preferredAccountName && accountName && preferredAccountName !== accountName) {
|
|
218
|
+
_warnOnce(`account-overwrite:${preferredAccountName}->${accountName}`, `[MULTI-BOT] Preferred account overwritten: '${preferredAccountName}' -> '${accountName}'. ` +
|
|
219
|
+
`All functions without explicit account params now target '${accountName}'.`);
|
|
220
|
+
}
|
|
221
|
+
preferredAccountId = accountId;
|
|
222
|
+
if (accountName)
|
|
223
|
+
preferredAccountName = accountName;
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Get the current preferred account (thread-safe).
|
|
228
|
+
* @returns {Promise<{id: string|null, name: string|null}>}
|
|
229
|
+
*/
|
|
230
|
+
async function getPreferredAccount() {
|
|
231
|
+
return await _preferredAccountLock.acquire(async () => {
|
|
232
|
+
return { id: preferredAccountId, name: preferredAccountName };
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Resolve an account ID to its human-readable name via chain lookup.
|
|
237
|
+
* Results are cached to prevent repeated lookups (fixes Issue #4).
|
|
238
|
+
* @param {string} accountRef - Account ID (e.g., '1.2.12345') or name
|
|
239
|
+
* @returns {Promise<string|null>} Account name or null if not found
|
|
240
|
+
*/
|
|
241
|
+
async function resolveAccountName(accountRef) {
|
|
242
|
+
if (!accountRef)
|
|
243
|
+
return null;
|
|
244
|
+
if (typeof accountRef !== 'string')
|
|
245
|
+
return null;
|
|
246
|
+
if (!/^1\.2\./.test(accountRef))
|
|
247
|
+
return accountRef;
|
|
248
|
+
return await _resolutionLock.acquire(async () => {
|
|
249
|
+
// Check cache first
|
|
250
|
+
const cacheKey = `id->${accountRef}`;
|
|
251
|
+
if (_accountResolutionCache.has(cacheKey)) {
|
|
252
|
+
return _accountResolutionCache.get(cacheKey);
|
|
253
|
+
}
|
|
254
|
+
try {
|
|
255
|
+
await waitForConnected();
|
|
256
|
+
const full = await BitShares.db.get_full_accounts([accountRef], false);
|
|
257
|
+
if (full && full[0] && full[0][1] && full[0][1].account && full[0][1].account.name) {
|
|
258
|
+
const name = full[0][1].account.name;
|
|
259
|
+
_accountResolutionCache.set(cacheKey, name);
|
|
260
|
+
// Also cache reverse mapping
|
|
261
|
+
_accountResolutionCache.set(`name->${name}`, accountRef);
|
|
262
|
+
return name;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
catch (err) {
|
|
266
|
+
// ignore resolution failures
|
|
267
|
+
}
|
|
268
|
+
_accountResolutionCache.set(cacheKey, null);
|
|
269
|
+
return null;
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Resolve an account name to its ID via chain lookup.
|
|
274
|
+
* Results are cached to prevent repeated lookups (fixes Issue #4).
|
|
275
|
+
* @param {string} accountName - Human-readable account name
|
|
276
|
+
* @returns {Promise<string|null>} Account ID or null if not found
|
|
277
|
+
*/
|
|
278
|
+
async function resolveAccountId(accountName) {
|
|
279
|
+
if (!accountName)
|
|
280
|
+
return null;
|
|
281
|
+
if (typeof accountName !== 'string')
|
|
282
|
+
return null;
|
|
283
|
+
// If already in ID format, return as-is
|
|
284
|
+
if (/^1\.2\.\d+$/.test(accountName))
|
|
285
|
+
return accountName;
|
|
286
|
+
return await _resolutionLock.acquire(async () => {
|
|
287
|
+
// Check cache first
|
|
288
|
+
const cacheKey = `name->${accountName}`;
|
|
289
|
+
if (_accountResolutionCache.has(cacheKey)) {
|
|
290
|
+
return _accountResolutionCache.get(cacheKey);
|
|
291
|
+
}
|
|
292
|
+
try {
|
|
293
|
+
await waitForConnected();
|
|
294
|
+
const full = await BitShares.db.get_full_accounts([accountName], false);
|
|
295
|
+
// full[0][0] is the account name (key), full[0][1] contains account data
|
|
296
|
+
if (full && full[0] && full[0][1] && full[0][1].account && full[0][1].account.id) {
|
|
297
|
+
const id = full[0][1].account.id;
|
|
298
|
+
_accountResolutionCache.set(cacheKey, id);
|
|
299
|
+
// Also cache reverse mapping
|
|
300
|
+
_accountResolutionCache.set(`id->${id}`, accountName);
|
|
301
|
+
return id;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
catch (err) {
|
|
305
|
+
// ignore resolution failures
|
|
306
|
+
}
|
|
307
|
+
_accountResolutionCache.set(cacheKey, null);
|
|
308
|
+
return null;
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
// Track active account subscriptions so we avoid duplicate listeners per account
|
|
312
|
+
// Map accountName -> { userCallbacks: Set<Function>, bsCallback: Function }
|
|
313
|
+
// Access MUST be protected by _subscriptionLock to prevent TOCTOU races (fixes Issue #1)
|
|
314
|
+
const accountSubscriptions = new Map();
|
|
315
|
+
/**
|
|
316
|
+
* Ensure a per-account BitShares subscription exists so we only subscribe once.
|
|
317
|
+
* @param {string} accountName - The name of the account to subscribe to.
|
|
318
|
+
* @param {Function} [userCallback] - Optional user callback to register before the native
|
|
319
|
+
* subscription's initial catch-up runs. Prevents initial catch-up fills from being lost.
|
|
320
|
+
* @returns {Promise<Object>} The subscription entry { userCallbacks, bsCallback }.
|
|
321
|
+
* @private
|
|
322
|
+
*/
|
|
323
|
+
async function _ensureAccountSubscriber(accountName, userCallback = null) {
|
|
324
|
+
return await _subscriptionLock.acquire(async () => {
|
|
325
|
+
// Check again inside lock to prevent duplicate subscriptions
|
|
326
|
+
if (accountSubscriptions.has(accountName)) {
|
|
327
|
+
return accountSubscriptions.get(accountName);
|
|
328
|
+
}
|
|
329
|
+
const userCallbacks = new Set();
|
|
330
|
+
if (typeof userCallback === 'function') {
|
|
331
|
+
userCallbacks.add(userCallback);
|
|
332
|
+
}
|
|
333
|
+
// BitShares callback that receives raw updates and dispatches to user callbacks
|
|
334
|
+
const bsCallback = async (updates) => {
|
|
335
|
+
// Filter for fill-related operations
|
|
336
|
+
const fills = updates.filter(update => {
|
|
337
|
+
const op = update.op;
|
|
338
|
+
return op && op[0] === FILL_PROCESSING.OPERATION_TYPE; // operation type for fill_order
|
|
339
|
+
});
|
|
340
|
+
if (fills.length > 0) {
|
|
341
|
+
// Call each registered user callback with the fills array
|
|
342
|
+
const failures = [];
|
|
343
|
+
for (const c of [...userCallbacks]) {
|
|
344
|
+
try {
|
|
345
|
+
await Promise.resolve(c(fills));
|
|
346
|
+
}
|
|
347
|
+
catch (e) {
|
|
348
|
+
failures.push(e);
|
|
349
|
+
chainOrdersLogger.error(`chain_orders listener error ${e.message}`);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
if (failures.length > 0) {
|
|
353
|
+
const err = new Error(`Fill listener delivery failed for ${failures.length} callback(s): ${failures.map(e => e.message || String(e)).join('; ')}`);
|
|
354
|
+
err.causes = failures;
|
|
355
|
+
throw err;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
try {
|
|
360
|
+
await withTimeout(BitShares.subscribe('account', bsCallback, accountName), NATIVE_CLIENT.SUBSCRIPTIONS.SUBSCRIBE_TIMEOUT_MS, 'BitShares.subscribe');
|
|
361
|
+
}
|
|
362
|
+
catch (subscribeErr) {
|
|
363
|
+
// Roll back any partial native-subscription state set up before the
|
|
364
|
+
// timeout or hard failure. BitShares.subscribe registers the entry
|
|
365
|
+
// in the native subscriptions map and adds bsCallback to
|
|
366
|
+
// entry.callbacks before its first await; if we fail before it
|
|
367
|
+
// returns, that state would otherwise be leaked and the next call
|
|
368
|
+
// for the same account would observe a half-dead subscription.
|
|
369
|
+
if (typeof BitShares.unsubscribe === 'function') {
|
|
370
|
+
try {
|
|
371
|
+
await BitShares.unsubscribe('account', bsCallback, accountName);
|
|
372
|
+
}
|
|
373
|
+
catch (rollbackErr) {
|
|
374
|
+
chainOrdersLogger.warn(`Failed to roll back partial subscription for ${accountName} after error: ` +
|
|
375
|
+
`${rollbackErr?.message || rollbackErr}`);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
throw subscribeErr;
|
|
379
|
+
}
|
|
380
|
+
const entry = { userCallbacks, bsCallback };
|
|
381
|
+
accountSubscriptions.set(accountName, entry);
|
|
382
|
+
return entry;
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Interactive account selection from stored encrypted keys.
|
|
387
|
+
* Prompts user to authenticate and select an account.
|
|
388
|
+
* Uses AsyncLock to prevent race conditions with concurrent listenForFills calls (fixes Issue #2, #5).
|
|
389
|
+
* @returns {Promise<Object>} { accountName, privateKey, id }
|
|
390
|
+
*/
|
|
391
|
+
async function selectAccount() {
|
|
392
|
+
const masterPassword = await chainKeys.authenticate();
|
|
393
|
+
const accountsData = chainKeys.loadAccounts();
|
|
394
|
+
const accountNames = Object.keys(accountsData.accounts);
|
|
395
|
+
if (accountNames.length === 0) {
|
|
396
|
+
throw new Error('No accounts found. Please add accounts using modules/chain_keys.ts');
|
|
397
|
+
}
|
|
398
|
+
console.log('Available accounts:');
|
|
399
|
+
accountNames.forEach((name, index) => {
|
|
400
|
+
console.log(`${index + 1}. ${name}`);
|
|
401
|
+
});
|
|
402
|
+
const choiceStr = await readInput('Select account number: ');
|
|
403
|
+
const choice = parseInt(choiceStr, 10) - 1;
|
|
404
|
+
if (choice < 0 || choice >= accountNames.length) {
|
|
405
|
+
throw new Error('Invalid account selection.');
|
|
406
|
+
}
|
|
407
|
+
const selectedAccount = accountNames[choice];
|
|
408
|
+
const privateKey = chainKeys.getPrivateKey(selectedAccount, masterPassword);
|
|
409
|
+
let selectedId = null;
|
|
410
|
+
try {
|
|
411
|
+
const full = await BitShares.db.get_full_accounts([selectedAccount], false);
|
|
412
|
+
if (full && full[0]) {
|
|
413
|
+
const candidateId = full[0][0];
|
|
414
|
+
if (candidateId && String(candidateId).startsWith('1.2.'))
|
|
415
|
+
selectedId = candidateId;
|
|
416
|
+
else if (full[0][1] && full[0][1].account && full[0][1].account.id)
|
|
417
|
+
selectedId = full[0][1].account.id;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
catch (e) {
|
|
421
|
+
console.error(`Failed to resolve account ID for ${selectedAccount}: ${e.message}`);
|
|
422
|
+
}
|
|
423
|
+
if (selectedId) {
|
|
424
|
+
await setPreferredAccount(selectedId, selectedAccount);
|
|
425
|
+
}
|
|
426
|
+
const pref = await getPreferredAccount();
|
|
427
|
+
console.log(`Selected account: ${selectedAccount} (ID: ${pref.id})`);
|
|
428
|
+
return { accountName: selectedAccount, privateKey: privateKey, id: pref.id };
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Check if a value is a credential daemon signing token.
|
|
432
|
+
* @param {*} value - Value to check
|
|
433
|
+
* @returns {boolean} True if value is a daemon signing token
|
|
434
|
+
*/
|
|
435
|
+
function isDaemonSigningToken(value) {
|
|
436
|
+
return getKeyStore().isDaemonSigningKey(value);
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Execute blockchain operations via the credential daemon.
|
|
440
|
+
* @param {string} accountName - Account name
|
|
441
|
+
* @param {Object} signingToken - Daemon signing token with socketPath, sessionId, botHmacSecret
|
|
442
|
+
* @param {Array<import('./types').CreatedOperation>} operations - Array of operation objects
|
|
443
|
+
* @returns {Promise<import('./types').BroadcastResult>} Broadcast result
|
|
444
|
+
*/
|
|
445
|
+
async function executeViaDaemonToken(accountName, signingToken, operations) {
|
|
446
|
+
return getKeyStore().executeOperations(accountName, operations, signingToken);
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Fetch a single limit order by id from the blockchain.
|
|
450
|
+
*
|
|
451
|
+
* Used by the sync engine as a targeted refetch when the cached `rawOnChain.for_sale`
|
|
452
|
+
* is observed to be smaller than the grid's own size (a "drift signal" — the chain
|
|
453
|
+
* value can only decrease, never grow on its own). The refetch is the only
|
|
454
|
+
* operation that re-anchors the cache to chain truth for an order whose in-memory
|
|
455
|
+
* baseline has fallen out of sync (e.g., a missed fill event).
|
|
456
|
+
*
|
|
457
|
+
* Return semantics:
|
|
458
|
+
* - returns the raw order object on success
|
|
459
|
+
* - returns `null` if the order is genuinely absent from the chain (`get_objects`
|
|
460
|
+
* returns null for missing ids) — this is the authoritative "order is gone"
|
|
461
|
+
* signal
|
|
462
|
+
* - THROWS on any other error (connection timeout, RPC failure, etc.). Callers
|
|
463
|
+
* use try/catch to distinguish "tried-and-gone" (null) from "tried-and-failed"
|
|
464
|
+
* (caught) and fall back to the cache.
|
|
465
|
+
*
|
|
466
|
+
* @param {string} orderId - BitShares limit order id (e.g. "1.7.572840453")
|
|
467
|
+
* @param {number} [timeoutMs] - Connection timeout in milliseconds. Defaults to
|
|
468
|
+
* the full CONNECTION_TIMEOUT_MS (30s); sync-engine callers should pass a
|
|
469
|
+
* smaller value so a disconnected node does not stall a fill cycle.
|
|
470
|
+
* @returns {Promise<Object|null>} Raw chain order object, or null if not found
|
|
471
|
+
* @throws {Error} On connection or RPC failure
|
|
472
|
+
*/
|
|
473
|
+
async function readSingleOrder(orderId, timeoutMs = TIMING.CONNECTION_TIMEOUT_MS) {
|
|
474
|
+
if (!orderId || typeof orderId !== 'string')
|
|
475
|
+
return null;
|
|
476
|
+
await waitForConnected(timeoutMs);
|
|
477
|
+
if (!BitShares || !BitShares.db || typeof BitShares.db.get_objects !== 'function') {
|
|
478
|
+
throw new Error('readSingleOrder: BitShares.db.get_objects unavailable');
|
|
479
|
+
}
|
|
480
|
+
const results = await BitShares.db.get_objects([orderId]);
|
|
481
|
+
const order = Array.isArray(results) ? results[0] : null;
|
|
482
|
+
if (!order)
|
|
483
|
+
return null;
|
|
484
|
+
if (order.id !== orderId)
|
|
485
|
+
return null;
|
|
486
|
+
return order;
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Fetch all open limit orders for an account from the blockchain.
|
|
490
|
+
* Uses AsyncLock to safely access preferred accountId (fixes Issue #2).
|
|
491
|
+
* @param {string|null} accountId - Account ID to query (uses preferred if null)
|
|
492
|
+
* @param {number} timeoutMs - Connection timeout in milliseconds
|
|
493
|
+
* @param {boolean} suppress_log - Whether to suppress the log
|
|
494
|
+
* @returns {Promise<Array>} Array of raw order objects from chain
|
|
495
|
+
*/
|
|
496
|
+
async function readOpenOrders(accountId = null, timeoutMs = TIMING.CONNECTION_TIMEOUT_MS, suppress_log = true) {
|
|
497
|
+
await waitForConnected(timeoutMs);
|
|
498
|
+
try {
|
|
499
|
+
let accId = accountId;
|
|
500
|
+
if (!accId) {
|
|
501
|
+
const pref = await getPreferredAccount();
|
|
502
|
+
accId = pref.id;
|
|
503
|
+
if (!accId) {
|
|
504
|
+
throw new Error('No account selected. Please call selectAccount() first or pass an account id');
|
|
505
|
+
}
|
|
506
|
+
_warnOnce(`readOpenOrders-no-accountId`, `[MULTI-BOT] readOpenOrders called without explicit accountId — using preferred '${pref.name || accId}'. ` +
|
|
507
|
+
`Pass accountId explicitly in multi-bot mode.`);
|
|
508
|
+
}
|
|
509
|
+
if (!accId) {
|
|
510
|
+
throw new Error('No account selected. Please call selectAccount() first or pass an account id');
|
|
511
|
+
}
|
|
512
|
+
const fullAccount = await BitShares.db.get_full_accounts([accId], false);
|
|
513
|
+
const orders = fullAccount[0][1].limit_orders || [];
|
|
514
|
+
if (!suppress_log) {
|
|
515
|
+
chainOrdersLogger.info(`Found ${orders.length} open orders for account ${accId}`);
|
|
516
|
+
}
|
|
517
|
+
return orders;
|
|
518
|
+
}
|
|
519
|
+
catch (error) {
|
|
520
|
+
chainOrdersLogger.error(`Error reading open orders: ${error.message}`);
|
|
521
|
+
throw error;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Subscribe to fill events for an account.
|
|
526
|
+
* Calls the callback when any of the account's orders are filled.
|
|
527
|
+
* Uses AsyncLock to safely access preferredAccount and subscription state (fixes Issue #2, #5).
|
|
528
|
+
*
|
|
529
|
+
* @param {string|Function} accountRef - Account name/id, or callback if using preferred
|
|
530
|
+
* @param {Function} [callback] - Function called with array of fill operations (when accountRef is a string)
|
|
531
|
+
* @returns {Function} Unsubscribe function to stop listening
|
|
532
|
+
*/
|
|
533
|
+
async function listenForFills(accountRef, callback) {
|
|
534
|
+
let userCallback = null;
|
|
535
|
+
let accountToken = null;
|
|
536
|
+
if (typeof accountRef === 'function' && arguments.length === 1) {
|
|
537
|
+
userCallback = accountRef;
|
|
538
|
+
}
|
|
539
|
+
else {
|
|
540
|
+
accountToken = accountRef;
|
|
541
|
+
userCallback = callback;
|
|
542
|
+
}
|
|
543
|
+
if (typeof userCallback !== 'function') {
|
|
544
|
+
chainOrdersLogger.error('listenForFills requires a callback function');
|
|
545
|
+
return () => { };
|
|
546
|
+
}
|
|
547
|
+
// Safely access preferredAccount using getPreferredAccount (fixes Issue #2, #5)
|
|
548
|
+
const pref = await getPreferredAccount();
|
|
549
|
+
let accountName = accountToken || pref.name;
|
|
550
|
+
if (!accountName && pref.id) {
|
|
551
|
+
accountName = await resolveAccountName(pref.id);
|
|
552
|
+
}
|
|
553
|
+
if (!accountName && accountToken) {
|
|
554
|
+
accountName = await resolveAccountName(accountToken);
|
|
555
|
+
}
|
|
556
|
+
if (!accountName) {
|
|
557
|
+
chainOrdersLogger.error('listenForFills requires an account name or a preferredAccount to be set');
|
|
558
|
+
return () => { };
|
|
559
|
+
}
|
|
560
|
+
let accountId = /^1\.2\./.test(accountToken || '') ? accountToken : pref.id;
|
|
561
|
+
if (!accountId) {
|
|
562
|
+
accountId = await resolveAccountId(accountName);
|
|
563
|
+
}
|
|
564
|
+
if (accountId) {
|
|
565
|
+
readOpenOrders(accountId, 30000, true).catch(error => chainOrdersLogger.error(`Error loading account for listening: ${error.message}`));
|
|
566
|
+
}
|
|
567
|
+
else {
|
|
568
|
+
chainOrdersLogger.warn('Unable to derive account id before listening for fills; skipping open-order prefetch.');
|
|
569
|
+
}
|
|
570
|
+
// Pass userCallback to _ensureAccountSubscriber so the native subscription's
|
|
571
|
+
// initial catch-up fills are dispatched to the caller (not lost).
|
|
572
|
+
// If the subscription already exists, the callback is added below instead.
|
|
573
|
+
const entry = await _ensureAccountSubscriber(accountName, userCallback);
|
|
574
|
+
// Add callback inside lock to prevent race with concurrent listenForFills calls.
|
|
575
|
+
// If _ensureAccountSubscriber already added it (new subscription), this is a no-op
|
|
576
|
+
// (Set.add deduplicates by reference).
|
|
577
|
+
const listenerCount = await _subscriptionLock.acquire(async () => {
|
|
578
|
+
entry.userCallbacks.add(userCallback);
|
|
579
|
+
return entry.userCallbacks.size;
|
|
580
|
+
});
|
|
581
|
+
chainOrdersLogger.info(`Listening for fills on account: ${accountName} (total listeners: ${listenerCount})`);
|
|
582
|
+
// Return an unsubscribe function that atomically removes the listener
|
|
583
|
+
return async function unsubscribe() {
|
|
584
|
+
try {
|
|
585
|
+
await _subscriptionLock.acquire(async () => {
|
|
586
|
+
entry.userCallbacks.delete(userCallback);
|
|
587
|
+
if (entry.userCallbacks.size === 0) {
|
|
588
|
+
try {
|
|
589
|
+
if (typeof BitShares.unsubscribe === 'function') {
|
|
590
|
+
await BitShares.unsubscribe('account', entry.bsCallback, accountName);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
catch (e) {
|
|
594
|
+
chainOrdersLogger.warn(`Unsubscribe failed: ${e.message}`);
|
|
595
|
+
}
|
|
596
|
+
accountSubscriptions.delete(accountName);
|
|
597
|
+
}
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
catch (e) {
|
|
601
|
+
chainOrdersLogger.error(`Error unsubscribing listenForFills ${e.message}`);
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Build a limit_order_update operation.
|
|
607
|
+
* @param {string} accountName - The name of the account.
|
|
608
|
+
* @param {string} orderId - The ID of the order to update.
|
|
609
|
+
* @param {Object} newParams - The new parameters for the order.
|
|
610
|
+
* @param {number} [newParams.amountToSell] - New amount to sell.
|
|
611
|
+
* @param {number} [newParams.minToReceive] - New minimum amount to receive.
|
|
612
|
+
* @param {number} [newParams.newPrice] - New price.
|
|
613
|
+
* @param {string} [newParams.orderType] - Type of the order ('buy' or 'sell').
|
|
614
|
+
* @param {string} [newParams.expiration] - New expiration date.
|
|
615
|
+
* @param {Object} [cachedOrder=null] - Optional already-fetched raw chain order.
|
|
616
|
+
* @returns {Promise<Object|null>} Operation object or null if no change.
|
|
617
|
+
* @throws {Error} If account or order not found, or if amounts exceed limits.
|
|
618
|
+
*/
|
|
619
|
+
async function buildUpdateOrderOp(accountName, orderId, newParams, cachedOrder = null) {
|
|
620
|
+
const accId = await resolveAccountId(accountName);
|
|
621
|
+
if (!accId)
|
|
622
|
+
throw new Error(`Account ${accountName} not found`);
|
|
623
|
+
// Use cached order if provided, otherwise fetch fresh from blockchain
|
|
624
|
+
let order = cachedOrder;
|
|
625
|
+
if (!order) {
|
|
626
|
+
const orders = await readOpenOrders(accId);
|
|
627
|
+
order = orders.find(o => o.id === orderId);
|
|
628
|
+
}
|
|
629
|
+
if (!order)
|
|
630
|
+
throw new Error(`Order ${orderId} not found`);
|
|
631
|
+
const sellAssetId = order.sell_price.base.asset_id;
|
|
632
|
+
const receiveAssetId = order.sell_price.quote.asset_id;
|
|
633
|
+
const sellPrecision = await _getAssetPrecision(sellAssetId);
|
|
634
|
+
const receivePrecision = await _getAssetPrecision(receiveAssetId);
|
|
635
|
+
const currentSellInt = toFiniteNumber(order.for_sale);
|
|
636
|
+
const currentSellFloat = blockchainToFloat(currentSellInt, sellPrecision);
|
|
637
|
+
const priceRatioBase = order.sell_price.base.amount;
|
|
638
|
+
const priceRatioQuote = order.sell_price.quote.amount;
|
|
639
|
+
const currentReceiveInt = Math.round((currentSellInt * priceRatioQuote) / priceRatioBase);
|
|
640
|
+
const currentReceiveFloat = blockchainToFloat(currentReceiveInt, receivePrecision);
|
|
641
|
+
// Determine target sell amount first.
|
|
642
|
+
// IMPORTANT: When amountToSell is undefined, use currentSellInt directly to avoid
|
|
643
|
+
// floating-point precision loss (blockchainToFloat -> floatToBlockchainInt roundtrip).
|
|
644
|
+
let newSellInt;
|
|
645
|
+
let newSellFloat;
|
|
646
|
+
if (newParams.amountToSell !== undefined && newParams.amountToSell !== null) {
|
|
647
|
+
newSellFloat = newParams.amountToSell;
|
|
648
|
+
newSellInt = floatToBlockchainInt(newSellFloat, sellPrecision);
|
|
649
|
+
}
|
|
650
|
+
else {
|
|
651
|
+
// Keep current amount exactly as-is on-chain, bypassing float conversion
|
|
652
|
+
newSellInt = currentSellInt;
|
|
653
|
+
newSellFloat = blockchainToFloat(currentSellInt, sellPrecision);
|
|
654
|
+
}
|
|
655
|
+
// Determine an initial receive amount for price-change detection.
|
|
656
|
+
// Policy:
|
|
657
|
+
// - If minToReceive is provided: use it as an absolute override.
|
|
658
|
+
// - Else if newPrice is provided: compute receive from the (new or current) sell amount.
|
|
659
|
+
// - Else: keep the existing on-chain price by scaling receive with sell.
|
|
660
|
+
let candidateReceiveInt;
|
|
661
|
+
if (newParams.minToReceive !== undefined && newParams.minToReceive !== null) {
|
|
662
|
+
candidateReceiveInt = floatToBlockchainInt(newParams.minToReceive, receivePrecision);
|
|
663
|
+
}
|
|
664
|
+
else if (newParams.newPrice !== undefined && newParams.newPrice !== null) {
|
|
665
|
+
const price = toFiniteNumber(newParams.newPrice);
|
|
666
|
+
const sellFloat = (newParams.amountToSell !== undefined && newParams.amountToSell !== null) ? newParams.amountToSell : currentSellFloat;
|
|
667
|
+
const receiveFloat = (newParams.orderType === 'sell')
|
|
668
|
+
? (sellFloat * price)
|
|
669
|
+
: (sellFloat / price);
|
|
670
|
+
candidateReceiveInt = floatToBlockchainInt(receiveFloat, receivePrecision);
|
|
671
|
+
}
|
|
672
|
+
else {
|
|
673
|
+
candidateReceiveInt = Math.round((newSellInt * priceRatioQuote) / priceRatioBase);
|
|
674
|
+
}
|
|
675
|
+
// Validate amounts before converting to blockchain integers / computing deltas
|
|
676
|
+
const candidateReceiveFloat = blockchainToFloat(candidateReceiveInt, receivePrecision);
|
|
677
|
+
if (!validateOrderAmountsWithinLimits(newSellFloat, candidateReceiveFloat, sellPrecision, receivePrecision)) {
|
|
678
|
+
throw new Error(`Cannot update order: calculated amounts exceed blockchain limits. ` +
|
|
679
|
+
`Sell: ${newSellFloat}, Receive: ${candidateReceiveFloat}. ` +
|
|
680
|
+
`This typically happens with extreme price values or mixed absolute/relative price bounds that diverge too far. ` +
|
|
681
|
+
`Consider adjusting minPrice/maxPrice configuration.`);
|
|
682
|
+
}
|
|
683
|
+
// Calculate delta (new - current)
|
|
684
|
+
// IMPORTANT: BitShares limit_order_update takes a delta for amount_to_sell
|
|
685
|
+
// But for the new_price, it takes the NEW total amounts.
|
|
686
|
+
let deltaSellInt = newSellInt - currentSellInt;
|
|
687
|
+
// PRECISION FIX: If delta is ±1 and it's due to floating-point precision loss,
|
|
688
|
+
// use the current amount to avoid unnecessary blockchain changes.
|
|
689
|
+
// This happens when newAmountToSell was rounded, causing floatToBlockchainInt
|
|
690
|
+
// to produce a different value than what's currently on-chain.
|
|
691
|
+
if (Math.abs(deltaSellInt) === 1 && newParams.amountToSell !== undefined && newParams.amountToSell !== null) {
|
|
692
|
+
const roundedNewSellInt = normalizeInt(newSellInt, sellPrecision);
|
|
693
|
+
const roundedCurrentSellInt = normalizeInt(currentSellInt, sellPrecision);
|
|
694
|
+
// If they match after rounding to precision, use the current amount (delta = 0)
|
|
695
|
+
if (roundedNewSellInt === roundedCurrentSellInt || Math.abs(roundedNewSellInt - roundedCurrentSellInt) <= 1) {
|
|
696
|
+
newSellInt = currentSellInt;
|
|
697
|
+
deltaSellInt = 0;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
// First, compute the receive amount with the current delta (not adjusted yet)
|
|
701
|
+
let newReceiveInt;
|
|
702
|
+
if (newParams.minToReceive !== undefined && newParams.minToReceive !== null) {
|
|
703
|
+
newReceiveInt = floatToBlockchainInt(newParams.minToReceive, receivePrecision);
|
|
704
|
+
}
|
|
705
|
+
else if (newParams.newPrice !== undefined && newParams.newPrice !== null) {
|
|
706
|
+
const price = toFiniteNumber(newParams.newPrice);
|
|
707
|
+
const receiveFloat = (newParams.orderType === 'sell')
|
|
708
|
+
? (newSellFloat * price)
|
|
709
|
+
: (newSellFloat / price);
|
|
710
|
+
newReceiveInt = floatToBlockchainInt(receiveFloat, receivePrecision);
|
|
711
|
+
}
|
|
712
|
+
else {
|
|
713
|
+
// Keep existing on-chain price ratio.
|
|
714
|
+
newReceiveInt = Math.round((newSellInt * priceRatioQuote) / priceRatioBase);
|
|
715
|
+
}
|
|
716
|
+
// Check if price or amount is actually changing
|
|
717
|
+
const priceChanged = newReceiveInt !== currentReceiveInt;
|
|
718
|
+
const amountChanged = deltaSellInt !== 0;
|
|
719
|
+
// PRECISION FIX for price-only updates: if price change is too small to detect (rounds to same value),
|
|
720
|
+
// adjust minToReceive by 1 unit in the appropriate direction to force the operation.
|
|
721
|
+
// This ensures partial orders are actually moved even when price change is < 1 blockchain unit.
|
|
722
|
+
if (!priceChanged && !amountChanged && newParams.newPrice !== undefined && newParams.newPrice !== null) {
|
|
723
|
+
if (newParams.orderType === 'sell') {
|
|
724
|
+
// SELL moving down = lower price = receive less → decrease by 1
|
|
725
|
+
newReceiveInt = currentReceiveInt - 1;
|
|
726
|
+
}
|
|
727
|
+
else if (newParams.orderType === 'buy') {
|
|
728
|
+
// BUY moving up = higher price = receive more → increase by 1
|
|
729
|
+
newReceiveInt = currentReceiveInt + 1;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
// Skip update only if BOTH amount and price are unchanged
|
|
733
|
+
if (!amountChanged && newReceiveInt === currentReceiveInt) {
|
|
734
|
+
return null;
|
|
735
|
+
}
|
|
736
|
+
// At this point, at least one field (amount or price) changed.
|
|
737
|
+
// If BOTH are unchanged (which shouldn't happen due to check above),
|
|
738
|
+
// we need to enforce a minimum delta of +1 to ensure operation validity
|
|
739
|
+
if (!amountChanged && !priceChanged) {
|
|
740
|
+
deltaSellInt = 1;
|
|
741
|
+
}
|
|
742
|
+
// Adjust newSellInt to strict logic: current + delta
|
|
743
|
+
const adjustedSellInt = currentSellInt + deltaSellInt;
|
|
744
|
+
// Recompute the final receive amount with the adjusted sell amount
|
|
745
|
+
if (newParams.minToReceive !== undefined && newParams.minToReceive !== null) {
|
|
746
|
+
newReceiveInt = floatToBlockchainInt(newParams.minToReceive, receivePrecision);
|
|
747
|
+
}
|
|
748
|
+
else if (newParams.newPrice !== undefined && newParams.newPrice !== null) {
|
|
749
|
+
const price = toFiniteNumber(newParams.newPrice);
|
|
750
|
+
const adjustedSellFloat = blockchainToFloat(adjustedSellInt, sellPrecision);
|
|
751
|
+
const receiveFloat = (newParams.orderType === 'sell')
|
|
752
|
+
? (adjustedSellFloat * price)
|
|
753
|
+
: (adjustedSellFloat / price);
|
|
754
|
+
newReceiveInt = floatToBlockchainInt(receiveFloat, receivePrecision);
|
|
755
|
+
}
|
|
756
|
+
else {
|
|
757
|
+
// Keep existing on-chain price ratio.
|
|
758
|
+
newReceiveInt = Math.round((adjustedSellInt * priceRatioQuote) / priceRatioBase);
|
|
759
|
+
}
|
|
760
|
+
const adjustedSellFloat = blockchainToFloat(adjustedSellInt, sellPrecision);
|
|
761
|
+
const finalReceiveFloat = blockchainToFloat(newReceiveInt, receivePrecision);
|
|
762
|
+
if (!validateOrderAmountsWithinLimits(adjustedSellFloat, finalReceiveFloat, sellPrecision, receivePrecision)) {
|
|
763
|
+
throw new Error(`Cannot update order: calculated amounts exceed blockchain limits. ` +
|
|
764
|
+
`Sell: ${adjustedSellFloat}, Receive: ${finalReceiveFloat}. ` +
|
|
765
|
+
`Consider adjusting minPrice/maxPrice configuration.`);
|
|
766
|
+
}
|
|
767
|
+
return {
|
|
768
|
+
op: {
|
|
769
|
+
op_name: 'limit_order_update',
|
|
770
|
+
op_data: {
|
|
771
|
+
fee: { amount: 0, asset_id: NATIVE_CLIENT.CHAIN.CORE_ASSET_ID },
|
|
772
|
+
seller: accId,
|
|
773
|
+
order: orderId,
|
|
774
|
+
new_price: {
|
|
775
|
+
base: {
|
|
776
|
+
amount: adjustedSellInt,
|
|
777
|
+
asset_id: sellAssetId
|
|
778
|
+
},
|
|
779
|
+
quote: {
|
|
780
|
+
amount: newReceiveInt,
|
|
781
|
+
asset_id: receiveAssetId
|
|
782
|
+
}
|
|
783
|
+
},
|
|
784
|
+
...(deltaSellInt !== 0 ? { delta_amount_to_sell: { amount: deltaSellInt, asset_id: sellAssetId } } : {}),
|
|
785
|
+
...(newParams.expiration ? { new_expiration: newParams.expiration } : {})
|
|
786
|
+
}
|
|
787
|
+
},
|
|
788
|
+
finalInts: { sell: adjustedSellInt, receive: newReceiveInt, sellAssetId, receiveAssetId }
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
/**
|
|
792
|
+
* Update an existing limit order on the blockchain.
|
|
793
|
+
* @param {string} accountName - The name of the account.
|
|
794
|
+
* @param {string|Object} privateKey - The private key for signing (or daemon signing token).
|
|
795
|
+
* @param {string} orderId - The ID of the order to update.
|
|
796
|
+
* @param {Object} newParams - The new parameters for the order.
|
|
797
|
+
* @returns {Promise<Object|null>} Success object or null if skipped.
|
|
798
|
+
* @throws {Error} If update fails.
|
|
799
|
+
*/
|
|
800
|
+
async function updateOrder(accountName, privateKey, orderId, newParams) {
|
|
801
|
+
try {
|
|
802
|
+
const buildResult = await buildUpdateOrderOp(accountName, orderId, newParams);
|
|
803
|
+
if (!buildResult) {
|
|
804
|
+
chainOrdersLogger.info(`Delta is 0; skipping limit_order_update (no change to amount_to_sell)`);
|
|
805
|
+
return null;
|
|
806
|
+
}
|
|
807
|
+
const { op } = buildResult;
|
|
808
|
+
if (isDaemonSigningToken(privateKey)) {
|
|
809
|
+
const result = await executeViaDaemonToken(accountName, privateKey, [op]);
|
|
810
|
+
chainOrdersLogger.info(`Order ${orderId} updated successfully`);
|
|
811
|
+
return { success: true, orderId, raw: result.raw, operation_results: result.operation_results };
|
|
812
|
+
}
|
|
813
|
+
const acc = await createAccountClient(accountName, privateKey);
|
|
814
|
+
await acc.initPromise;
|
|
815
|
+
const tx = acc.newTx();
|
|
816
|
+
// Use explicit method call for robustness
|
|
817
|
+
if (typeof tx.limit_order_update === 'function') {
|
|
818
|
+
tx.limit_order_update(op.op_data);
|
|
819
|
+
}
|
|
820
|
+
else {
|
|
821
|
+
throw new Error(`Transaction builder does not support limit_order_update`);
|
|
822
|
+
}
|
|
823
|
+
await tx.broadcast();
|
|
824
|
+
chainOrdersLogger.info(`Order ${orderId} updated successfully`);
|
|
825
|
+
return { success: true, orderId };
|
|
826
|
+
}
|
|
827
|
+
catch (error) {
|
|
828
|
+
chainOrdersLogger.error(`Error updating order: ${error.message}`);
|
|
829
|
+
throw error;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
/**
|
|
833
|
+
* Build a limit_order_create operation.
|
|
834
|
+
* @param {string} accountName - The name of the account.
|
|
835
|
+
* @param {number} amountToSell - The amount of the asset to sell.
|
|
836
|
+
* @param {string} sellAssetId - The ID of the asset to sell.
|
|
837
|
+
* @param {number} minToReceive - The minimum amount of the asset to receive.
|
|
838
|
+
* @param {string} receiveAssetId - The ID of the asset to receive.
|
|
839
|
+
* @param {string} [expiration] - The expiration date for the order.
|
|
840
|
+
* @returns {Promise<Object|null>} The operation object, or null if amounts would round to 0.
|
|
841
|
+
* @throws {Error} If account not found.
|
|
842
|
+
*/
|
|
843
|
+
async function buildCreateOrderOp(accountName, amountToSell, sellAssetId, minToReceive, receiveAssetId, expiration) {
|
|
844
|
+
const accId = await resolveAccountId(accountName);
|
|
845
|
+
if (!accId)
|
|
846
|
+
throw new Error(`Account ${accountName} not found`);
|
|
847
|
+
if (!expiration) {
|
|
848
|
+
const now = new Date();
|
|
849
|
+
now.setFullYear(now.getFullYear() + 1);
|
|
850
|
+
expiration = now.toISOString().split('T')[0] + 'T23:59:59';
|
|
851
|
+
}
|
|
852
|
+
const sellPrecision = await _getAssetPrecision(sellAssetId);
|
|
853
|
+
const receivePrecision = await _getAssetPrecision(receiveAssetId);
|
|
854
|
+
const amountToSellInt = floatToBlockchainInt(amountToSell, sellPrecision);
|
|
855
|
+
const minToReceiveInt = floatToBlockchainInt(minToReceive, receivePrecision);
|
|
856
|
+
// CRITICAL: Validate order amounts before creating operation
|
|
857
|
+
// This prevents "Assert Exception: min_to_receive.amount > 0" errors from BitShares
|
|
858
|
+
// when order sizes are too small and round to 0 after precision conversion
|
|
859
|
+
// Returns null instead of throwing to allow caller to skip invalid orders gracefully
|
|
860
|
+
if (!validateOrderAmountsWithinLimits(amountToSell, minToReceive, sellPrecision, receivePrecision)) {
|
|
861
|
+
chainOrdersLogger.warn(`Order skipped: amounts would round to 0 on blockchain\n` +
|
|
862
|
+
` Float values: sell=${amountToSell}, receive=${minToReceive}\n` +
|
|
863
|
+
` Blockchain integers: sell=${amountToSellInt} (prec ${sellPrecision}), receive=${minToReceiveInt} (prec ${receivePrecision})\n` +
|
|
864
|
+
` Required: both > 0`);
|
|
865
|
+
return null;
|
|
866
|
+
}
|
|
867
|
+
const op = {
|
|
868
|
+
op_name: 'limit_order_create',
|
|
869
|
+
op_data: {
|
|
870
|
+
fee: { amount: 0, asset_id: NATIVE_CLIENT.CHAIN.CORE_ASSET_ID },
|
|
871
|
+
seller: accId,
|
|
872
|
+
amount_to_sell: { amount: amountToSellInt, asset_id: sellAssetId },
|
|
873
|
+
min_to_receive: { amount: minToReceiveInt, asset_id: receiveAssetId },
|
|
874
|
+
expiration: expiration,
|
|
875
|
+
fill_or_kill: false,
|
|
876
|
+
extensions: []
|
|
877
|
+
}
|
|
878
|
+
};
|
|
879
|
+
return {
|
|
880
|
+
op,
|
|
881
|
+
finalInts: { sell: amountToSellInt, receive: minToReceiveInt, sellAssetId, receiveAssetId }
|
|
882
|
+
};
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* Create a new limit order on the blockchain.
|
|
886
|
+
* @param {string} accountName - The name of the account.
|
|
887
|
+
* @param {string|Object} privateKey - The private key for signing (or daemon signing token).
|
|
888
|
+
* @param {number} amountToSell - The amount of the asset to sell.
|
|
889
|
+
* @param {string} sellAssetId - The ID of the asset to sell.
|
|
890
|
+
* @param {number} minToReceive - The minimum amount of the asset to receive.
|
|
891
|
+
* @param {string} receiveAssetId - The ID of the asset to receive.
|
|
892
|
+
* @param {string} [expiration] - The expiration date for the order.
|
|
893
|
+
* @param {boolean} [dryRun=false] - Whether to simulate the operation.
|
|
894
|
+
* @returns {Promise<Object>} The transaction result or dry run info.
|
|
895
|
+
* @throws {Error} If account not found or creation fails.
|
|
896
|
+
*/
|
|
897
|
+
async function createOrder(accountName, privateKey, amountToSell, sellAssetId, minToReceive, receiveAssetId, expiration, dryRun = false) {
|
|
898
|
+
try {
|
|
899
|
+
const buildResult = await buildCreateOrderOp(accountName, amountToSell, sellAssetId, minToReceive, receiveAssetId, expiration);
|
|
900
|
+
if (!buildResult)
|
|
901
|
+
return { skipped: true };
|
|
902
|
+
const { op } = buildResult;
|
|
903
|
+
if (dryRun) {
|
|
904
|
+
chainOrdersLogger.info(`Dry run: Limit order prepared for account ${accountName} (not broadcasted)`);
|
|
905
|
+
return { dryRun: true, params: op.op_data };
|
|
906
|
+
}
|
|
907
|
+
if (isDaemonSigningToken(privateKey)) {
|
|
908
|
+
const result = await executeViaDaemonToken(accountName, privateKey, [op]);
|
|
909
|
+
chainOrdersLogger.info(`Limit order created successfully for account ${accountName}`);
|
|
910
|
+
return result;
|
|
911
|
+
}
|
|
912
|
+
const acc = await createAccountClient(accountName, privateKey);
|
|
913
|
+
await acc.initPromise;
|
|
914
|
+
const tx = acc.newTx();
|
|
915
|
+
// Invoke standard method directly
|
|
916
|
+
tx.limit_order_create(op.op_data);
|
|
917
|
+
const result = await tx.broadcast();
|
|
918
|
+
chainOrdersLogger.info(`Limit order created successfully for account ${accountName}`);
|
|
919
|
+
return result;
|
|
920
|
+
}
|
|
921
|
+
catch (error) {
|
|
922
|
+
chainOrdersLogger.error(`Error creating limit order: ${error.message}`);
|
|
923
|
+
throw error;
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
/**
|
|
927
|
+
* Build a limit_order_cancel operation.
|
|
928
|
+
* @param {string} accountName - The name of the account.
|
|
929
|
+
* @param {string} orderId - The ID of the order to cancel.
|
|
930
|
+
* @returns {Promise<Object>} The operation object.
|
|
931
|
+
* @throws {Error} If account not found.
|
|
932
|
+
*/
|
|
933
|
+
async function buildCancelOrderOp(accountName, orderId) {
|
|
934
|
+
const accId = await resolveAccountId(accountName);
|
|
935
|
+
if (!accId)
|
|
936
|
+
throw new Error(`Account ${accountName} not found`);
|
|
937
|
+
return {
|
|
938
|
+
op_name: 'limit_order_cancel',
|
|
939
|
+
op_data: {
|
|
940
|
+
fee: { amount: 0, asset_id: NATIVE_CLIENT.CHAIN.CORE_ASSET_ID },
|
|
941
|
+
fee_paying_account: accId,
|
|
942
|
+
order: orderId
|
|
943
|
+
}
|
|
944
|
+
};
|
|
945
|
+
}
|
|
946
|
+
/**
|
|
947
|
+
* Cancel an existing limit order on the blockchain.
|
|
948
|
+
* @param {string} accountName - The name of the account.
|
|
949
|
+
* @param {string|Object} privateKey - The private key for signing (or daemon signing token).
|
|
950
|
+
* @param {string} orderId - The ID of the order to cancel.
|
|
951
|
+
* @returns {Promise<Object>} Success object with order ID and verification metadata.
|
|
952
|
+
* @throws {Error} If cancellation fails.
|
|
953
|
+
*/
|
|
954
|
+
async function cancelOrder(accountName, privateKey, orderId) {
|
|
955
|
+
let accountId = null;
|
|
956
|
+
try {
|
|
957
|
+
const op = await buildCancelOrderOp(accountName, orderId);
|
|
958
|
+
accountId = op.op_data.fee_paying_account;
|
|
959
|
+
if (isDaemonSigningToken(privateKey)) {
|
|
960
|
+
const result = await executeViaDaemonToken(accountName, privateKey, [op]);
|
|
961
|
+
recordOwnCancel(orderId);
|
|
962
|
+
chainOrdersLogger.info(`Order ${orderId} cancelled successfully`);
|
|
963
|
+
return { success: true, orderId, verified: true, raw: result.raw, operation_results: result.operation_results };
|
|
964
|
+
}
|
|
965
|
+
const acc = await createAccountClient(accountName, privateKey);
|
|
966
|
+
await acc.initPromise;
|
|
967
|
+
const tx = acc.newTx();
|
|
968
|
+
// Explicit call
|
|
969
|
+
tx.limit_order_cancel(op.op_data);
|
|
970
|
+
await tx.broadcast();
|
|
971
|
+
recordOwnCancel(orderId);
|
|
972
|
+
chainOrdersLogger.info(`Order ${orderId} cancelled successfully`);
|
|
973
|
+
return { success: true, orderId, verified: true };
|
|
974
|
+
}
|
|
975
|
+
catch (error) {
|
|
976
|
+
if (accountId) {
|
|
977
|
+
try {
|
|
978
|
+
const openOrders = await readOpenOrders(accountId, TIMING.CONNECTION_TIMEOUT_MS, true);
|
|
979
|
+
const stillPresent = Array.isArray(openOrders) && openOrders.some(order => String(order?.id ?? '') === String(orderId));
|
|
980
|
+
if (!stillPresent) {
|
|
981
|
+
chainOrdersLogger.info(`Order ${orderId} cancellation confirmed after broadcast failure`);
|
|
982
|
+
return { success: true, orderId, verified: true, verifiedAfterFailure: true };
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
catch (_) {
|
|
986
|
+
// Fall through to the original error.
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
chainOrdersLogger.error(`Error cancelling order: ${error.message}`);
|
|
990
|
+
throw error;
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
/**
|
|
994
|
+
* Execute a batch of operations in a single transaction.
|
|
995
|
+
* @param {string} accountName - Account paying fees (usually the bot account)
|
|
996
|
+
* @param {string|Object} privateKey - Private key for signing (or daemon signing token)
|
|
997
|
+
* @param {Array} operations - Array of operation objects { op_name, op_data } returned by build helpers
|
|
998
|
+
* @returns {Promise<Object>} Transaction result
|
|
999
|
+
*/
|
|
1000
|
+
async function executeBatch(accountName, privateKey, operations) {
|
|
1001
|
+
if (!operations || operations.length === 0)
|
|
1002
|
+
return { success: true, operations: 0 };
|
|
1003
|
+
try {
|
|
1004
|
+
if (isDaemonSigningToken(privateKey)) {
|
|
1005
|
+
const result = await executeViaDaemonToken(accountName, privateKey, operations);
|
|
1006
|
+
recordOwnCancelOps(operations);
|
|
1007
|
+
return result;
|
|
1008
|
+
}
|
|
1009
|
+
const acc = await createAccountClient(accountName, privateKey);
|
|
1010
|
+
await acc.initPromise;
|
|
1011
|
+
const tx = acc.newTx();
|
|
1012
|
+
for (const op of operations) {
|
|
1013
|
+
if (typeof tx[op.op_name] === 'function') {
|
|
1014
|
+
tx[op.op_name](op.op_data);
|
|
1015
|
+
}
|
|
1016
|
+
else {
|
|
1017
|
+
chainOrdersLogger.warn(`Transaction builder missing method for ${op.op_name}`);
|
|
1018
|
+
throw new Error(`Transaction builder does not support ${op.op_name}`);
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
const result = await tx.broadcast();
|
|
1022
|
+
// Record own-cancel correlation for the self-cancel guard in the fill
|
|
1023
|
+
// consumer. Without this, batched cancels (the dominant COW path) would
|
|
1024
|
+
// skip the ring buffer and the guard would not recognize their
|
|
1025
|
+
// propagation artifacts as non-economic. Only fires after a successful
|
|
1026
|
+
// broadcast so failed batches never poison the buffer.
|
|
1027
|
+
recordOwnCancelOps(operations);
|
|
1028
|
+
// Normalize broadcast response shape across node variants.
|
|
1029
|
+
const operationResults = (result && Array.isArray(result.operation_results) && result.operation_results.length > 0 && result.operation_results) ||
|
|
1030
|
+
(result && result.trx && Array.isArray(result.trx.operation_results) && result.trx.operation_results.length > 0 && result.trx.operation_results) ||
|
|
1031
|
+
(Array.isArray(result) && result[0] && result[0].trx && Array.isArray(result[0].trx.operation_results) && result[0].trx.operation_results.length > 0 && result[0].trx.operation_results) ||
|
|
1032
|
+
[];
|
|
1033
|
+
return {
|
|
1034
|
+
success: true,
|
|
1035
|
+
raw: result,
|
|
1036
|
+
operation_results: operationResults
|
|
1037
|
+
};
|
|
1038
|
+
}
|
|
1039
|
+
catch (error) {
|
|
1040
|
+
chainOrdersLogger.error(`Error executing batch transaction: ${error.message}`);
|
|
1041
|
+
throw error;
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
/**
|
|
1045
|
+
* Fetch on-chain balances and locked amounts for the specified account and assets.
|
|
1046
|
+
* This helper only reads on-chain balances and open-order locks and MUST NOT be
|
|
1047
|
+
* mixed with the manager's internal "available for orders" calculations.
|
|
1048
|
+
*
|
|
1049
|
+
* @param {String} accountRef - account name or id
|
|
1050
|
+
* @param {Array<String>} assets - array of asset ids or symbols to query (e.g. ['1.3.0','IOB.XRP'])
|
|
1051
|
+
* @returns {Object} mapping assetRef -> { assetId, symbol, precision, freeRaw, lockedRaw, free, locked, total }
|
|
1052
|
+
*/
|
|
1053
|
+
async function getOnChainAssetBalances(accountRef, assets) {
|
|
1054
|
+
if (!accountRef)
|
|
1055
|
+
return {};
|
|
1056
|
+
try {
|
|
1057
|
+
await waitForConnected();
|
|
1058
|
+
// Resolve account id if name provided
|
|
1059
|
+
let accountId = accountRef;
|
|
1060
|
+
if (typeof accountRef === 'string' && !/^1\.2\./.test(accountRef)) {
|
|
1061
|
+
const full = await BitShares.db.get_full_accounts([accountRef], false);
|
|
1062
|
+
if (Array.isArray(full) && full[0] && full[0][0])
|
|
1063
|
+
accountId = full[0][0];
|
|
1064
|
+
}
|
|
1065
|
+
// Fetch full account data so we have balances and limit_orders
|
|
1066
|
+
const full = await BitShares.db.get_full_accounts([accountId], false);
|
|
1067
|
+
if (!Array.isArray(full) || !full[0] || !full[0][1])
|
|
1068
|
+
return {};
|
|
1069
|
+
const accountData = full[0][1] || {};
|
|
1070
|
+
const balances = accountData.balances || [];
|
|
1071
|
+
const limitOrders = accountData.limit_orders || [];
|
|
1072
|
+
// Build free balances map by asset id
|
|
1073
|
+
const freeInt = new Map();
|
|
1074
|
+
for (const b of balances) {
|
|
1075
|
+
const aid = String(b.asset_type || b.asset_id || b.asset);
|
|
1076
|
+
const val = toFiniteNumber(b.balance || b.amount);
|
|
1077
|
+
freeInt.set(aid, (freeInt.get(aid) || 0) + val);
|
|
1078
|
+
}
|
|
1079
|
+
// Build locked map (for_sale) grouped by base asset id
|
|
1080
|
+
const lockedInt = new Map();
|
|
1081
|
+
for (const o of limitOrders) {
|
|
1082
|
+
if (!o || !o.sell_price || !o.sell_price.base)
|
|
1083
|
+
continue;
|
|
1084
|
+
const baseId = String(o.sell_price.base.asset_id);
|
|
1085
|
+
const forSale = toFiniteNumber(o.for_sale);
|
|
1086
|
+
lockedInt.set(baseId, (lockedInt.get(baseId) || 0) + forSale);
|
|
1087
|
+
}
|
|
1088
|
+
// If assets omitted, build list from balances and limit_orders
|
|
1089
|
+
let assetList = assets;
|
|
1090
|
+
if (!assetList || !Array.isArray(assetList) || assetList.length === 0) {
|
|
1091
|
+
assetList = [];
|
|
1092
|
+
for (const b of balances)
|
|
1093
|
+
assetList.push(String(b.asset_type || b.asset_id || b.asset));
|
|
1094
|
+
for (const o of limitOrders) {
|
|
1095
|
+
if (!o || !o.sell_price || !o.sell_price.base)
|
|
1096
|
+
continue;
|
|
1097
|
+
assetList.push(String(o.sell_price.base.asset_id));
|
|
1098
|
+
}
|
|
1099
|
+
// de-duplicate
|
|
1100
|
+
assetList = Array.from(new Set(assetList));
|
|
1101
|
+
}
|
|
1102
|
+
const out = {};
|
|
1103
|
+
for (const a of assetList) {
|
|
1104
|
+
// resolve asset id and precision
|
|
1105
|
+
let aid = a;
|
|
1106
|
+
try {
|
|
1107
|
+
if (!/^1\.3\./.test(String(a))) {
|
|
1108
|
+
// symbol -> asset
|
|
1109
|
+
const res = await BitShares.db.lookup_asset_symbols([String(a)]).catch(() => null);
|
|
1110
|
+
if (res && res[0] && res[0].id)
|
|
1111
|
+
aid = res[0].id;
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
catch (e) {
|
|
1115
|
+
chainOrdersLogger.warn(`lookup_asset_symbols failed for ${a}: ${e.message}`);
|
|
1116
|
+
}
|
|
1117
|
+
// try to get precision and symbol
|
|
1118
|
+
let precision = null;
|
|
1119
|
+
let symbol = String(a);
|
|
1120
|
+
try {
|
|
1121
|
+
const am = await BitShares.db.get_assets([aid]).catch(() => null);
|
|
1122
|
+
if (Array.isArray(am) && am[0]) {
|
|
1123
|
+
precision = typeof am[0].precision === 'number' ? am[0].precision : null;
|
|
1124
|
+
symbol = am[0].symbol || symbol;
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
catch (e) {
|
|
1128
|
+
chainOrdersLogger.warn(`Failed to fetch asset data for ${aid}: ${e.message}`);
|
|
1129
|
+
}
|
|
1130
|
+
if (precision === null) {
|
|
1131
|
+
chainOrdersLogger.error(`CRITICAL: Could not determine precision for asset ${aid}. Skipping balance entry to prevent massive scaling errors.`);
|
|
1132
|
+
continue;
|
|
1133
|
+
}
|
|
1134
|
+
const freeRaw = freeInt.get(String(aid)) || 0;
|
|
1135
|
+
const lockedRaw = lockedInt.get(String(aid)) || 0;
|
|
1136
|
+
const free = blockchainToFloat(freeRaw, precision);
|
|
1137
|
+
const locked = blockchainToFloat(lockedRaw, precision);
|
|
1138
|
+
out[String(a)] = { assetId: String(aid), symbol, precision, freeRaw, lockedRaw, free, locked, total: free + locked };
|
|
1139
|
+
}
|
|
1140
|
+
return out;
|
|
1141
|
+
}
|
|
1142
|
+
catch (err) {
|
|
1143
|
+
chainOrdersLogger.error(`getOnChainAssetBalances failed: ${err.message}`);
|
|
1144
|
+
return {};
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
/**
|
|
1148
|
+
* Build a liquidity_pool_exchange operation for swapping assets via AMM pool.
|
|
1149
|
+
* @param {string} accountId - The blockchain account ID (1.2.x)
|
|
1150
|
+
* @param {string} poolId - The liquidity pool ID (1.19.x)
|
|
1151
|
+
* @param {number} sellAmountInt - Amount to sell (blockchain integer, not float)
|
|
1152
|
+
* @param {string} sellAssetId - Asset ID to sell
|
|
1153
|
+
* @param {number} minReceiveInt - Minimum amount to receive (blockchain integer)
|
|
1154
|
+
* @param {string} receiveAssetId - Asset ID to receive
|
|
1155
|
+
* @returns {Object} The operation object with op_name and op_data
|
|
1156
|
+
*/
|
|
1157
|
+
function buildLiquidityPoolExchangeOp(accountId, poolId, sellAmountInt, sellAssetId, minReceiveInt, receiveAssetId) {
|
|
1158
|
+
return {
|
|
1159
|
+
op_name: 'liquidity_pool_exchange',
|
|
1160
|
+
op_data: {
|
|
1161
|
+
fee: { amount: 0, asset_id: NATIVE_CLIENT.CHAIN.CORE_ASSET_ID },
|
|
1162
|
+
account: accountId,
|
|
1163
|
+
pool: poolId,
|
|
1164
|
+
amount_to_sell: { amount: sellAmountInt, asset_id: sellAssetId },
|
|
1165
|
+
min_to_receive: { amount: minReceiveInt, asset_id: receiveAssetId },
|
|
1166
|
+
extensions: []
|
|
1167
|
+
}
|
|
1168
|
+
};
|
|
1169
|
+
}
|
|
1170
|
+
/**
|
|
1171
|
+
* Get the current fill processing mode.
|
|
1172
|
+
* @returns {string} 'history' or 'open'
|
|
1173
|
+
*/
|
|
1174
|
+
function getFillProcessingMode() {
|
|
1175
|
+
return FILL_PROCESSING_MODE;
|
|
1176
|
+
}
|
|
1177
|
+
module.exports = {
|
|
1178
|
+
selectAccount,
|
|
1179
|
+
setPreferredAccount,
|
|
1180
|
+
resolveAccountId,
|
|
1181
|
+
resolveAccountName,
|
|
1182
|
+
readOpenOrders,
|
|
1183
|
+
readSingleOrder,
|
|
1184
|
+
listenForFills,
|
|
1185
|
+
updateOrder,
|
|
1186
|
+
createOrder,
|
|
1187
|
+
cancelOrder,
|
|
1188
|
+
getOnChainAssetBalances,
|
|
1189
|
+
getFillProcessingMode,
|
|
1190
|
+
FILL_PROCESSING_MODE,
|
|
1191
|
+
buildUpdateOrderOp,
|
|
1192
|
+
buildCreateOrderOp,
|
|
1193
|
+
buildCancelOrderOp,
|
|
1194
|
+
buildLiquidityPoolExchangeOp,
|
|
1195
|
+
executeBatch,
|
|
1196
|
+
wasRecentlyOwnCancelled,
|
|
1197
|
+
recordOwnCancel,
|
|
1198
|
+
BroadcastUncertainError,
|
|
1199
|
+
// Note: authentication and key retrieval moved to modules/chain_keys.ts
|
|
1200
|
+
};
|
|
1201
|
+
//# sourceMappingURL=chain_orders.js.map
|