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,865 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { NATIVE_CLIENT } = require('../constants');
|
|
3
|
+
const { SUBSCRIPTIONS, OPERATIONS } = NATIVE_CLIENT;
|
|
4
|
+
const SUBSCRIBE_CALLBACK_ID = SUBSCRIPTIONS.CALLBACK_ID;
|
|
5
|
+
const OP_FILL_ORDER = OPERATIONS.FILL_ORDER;
|
|
6
|
+
const Logger = require('../logger');
|
|
7
|
+
const subscriptionsLogger = new Logger('Subscriptions');
|
|
8
|
+
function createSubscriptionManager(chainClient) {
|
|
9
|
+
const subscriptions = new Map();
|
|
10
|
+
let unsubscribeNotice = null;
|
|
11
|
+
const reconnectRetryDelayMs = Number.isFinite(SUBSCRIPTIONS.RECONNECT_RETRY_DELAY_MS)
|
|
12
|
+
? Math.max(1000, SUBSCRIPTIONS.RECONNECT_RETRY_DELAY_MS)
|
|
13
|
+
: 5000;
|
|
14
|
+
const noticeCoalesceMs = Number.isFinite(SUBSCRIPTIONS.NOTICE_COALESCE_MS)
|
|
15
|
+
? Math.max(0, SUBSCRIPTIONS.NOTICE_COALESCE_MS)
|
|
16
|
+
: 0;
|
|
17
|
+
// Per-subscription pending scan state for coalescing. Keyed by sub object
|
|
18
|
+
// (Map iteration order is stable so we can reuse a single timer per entry).
|
|
19
|
+
const pendingScans = new Map();
|
|
20
|
+
// Subscription health watchdog timer and re-entrancy guard.
|
|
21
|
+
let subscriptionHealthTimer = null;
|
|
22
|
+
let healthCheckInProgress = false;
|
|
23
|
+
function parseObjectIdInstance(id) {
|
|
24
|
+
if (typeof id !== 'string')
|
|
25
|
+
return Number.NaN;
|
|
26
|
+
const match = id.match(/\.(\d+)$/);
|
|
27
|
+
return match ? Number(match[1]) : Number.NaN;
|
|
28
|
+
}
|
|
29
|
+
function sortEntriesOldestFirst(entries) {
|
|
30
|
+
return entries.sort((left, right) => {
|
|
31
|
+
const leftInstance = parseObjectIdInstance(left?.id);
|
|
32
|
+
const rightInstance = parseObjectIdInstance(right?.id);
|
|
33
|
+
if (!Number.isFinite(leftInstance) || !Number.isFinite(rightInstance)) {
|
|
34
|
+
return String(left?.id || '').localeCompare(String(right?.id || ''));
|
|
35
|
+
}
|
|
36
|
+
return leftInstance - rightInstance;
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function decrementObjectId(id) {
|
|
40
|
+
if (typeof id !== 'string')
|
|
41
|
+
return null;
|
|
42
|
+
const match = id.match(/^(.+\.)(\d+)$/);
|
|
43
|
+
if (!match)
|
|
44
|
+
return null;
|
|
45
|
+
const instance = Number(match[2]);
|
|
46
|
+
if (!Number.isSafeInteger(instance) || instance <= 0)
|
|
47
|
+
return null;
|
|
48
|
+
return `${match[1]}${instance - 1}`;
|
|
49
|
+
}
|
|
50
|
+
function warnSubscription(sub, message, err = null) {
|
|
51
|
+
const account = sub?.accountName || sub?.accountId || 'unknown';
|
|
52
|
+
const detail = err?.message ? `: ${err.message}` : '';
|
|
53
|
+
subscriptionsLogger.warn(`${message} for ${account}${detail}`);
|
|
54
|
+
}
|
|
55
|
+
function getAccountHistoryFetcher() {
|
|
56
|
+
return chainClient.history?.getAccountHistory
|
|
57
|
+
|| chainClient.history?.get_account_history
|
|
58
|
+
|| (chainClient.history?.getAccountHistoryOperations
|
|
59
|
+
? ((accountId, stop, limit, start) => chainClient.history.getAccountHistoryOperations(accountId, OP_FILL_ORDER, start, stop, limit))
|
|
60
|
+
: null)
|
|
61
|
+
|| ((...args) => chainClient.history.call('get_account_history', args));
|
|
62
|
+
}
|
|
63
|
+
async function fetchFullAccountWithRetry(sub, subscribe = false) {
|
|
64
|
+
const accountRef = sub.accountId || sub.accountName;
|
|
65
|
+
let lastErr = null;
|
|
66
|
+
for (let attempt = 1; attempt <= 2; attempt++) {
|
|
67
|
+
try {
|
|
68
|
+
const accounts = await chainClient.db.get_full_accounts([accountRef], subscribe);
|
|
69
|
+
const account = accounts?.[0]?.[1];
|
|
70
|
+
if (account)
|
|
71
|
+
return account;
|
|
72
|
+
warnSubscription(sub, `get_full_accounts returned no account data on attempt ${attempt}`);
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
lastErr = err;
|
|
76
|
+
warnSubscription(sub, `get_full_accounts failed on attempt ${attempt}`, err);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (lastErr)
|
|
80
|
+
throw lastErr;
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
// btsdex parity: use get_account_history (unfiltered) instead of
|
|
84
|
+
// get_account_history_operations (type-filtered). The type-filtered API
|
|
85
|
+
// walks a per-account linked list and may miss fill_order operations even
|
|
86
|
+
// when they exist on chain for the account. The unfiltered API uses the
|
|
87
|
+
// efficient by_op index and returns ALL operation types. We filter for
|
|
88
|
+
// OP_FILL_ORDER client-side in processObjects.
|
|
89
|
+
async function fetchFillHistoryEntries(accountId, cursorHistoryId, options = {}) {
|
|
90
|
+
const fetchPage = getAccountHistoryFetcher();
|
|
91
|
+
const entries = [];
|
|
92
|
+
const seenIds = new Set();
|
|
93
|
+
const cursorInstance = parseObjectIdInstance(cursorHistoryId);
|
|
94
|
+
// Scan history using get_account_history (unfiltered, uses by_op index).
|
|
95
|
+
// Parameters: (accountId, stop, limit, start)
|
|
96
|
+
// API returns entries from start (newest) down to stop (cursor), with
|
|
97
|
+
// start=0 being replaced by the server with the max/head operation ID.
|
|
98
|
+
let startHistoryId = SUBSCRIPTIONS.HISTORY_API_OBJECT;
|
|
99
|
+
let pagesFetched = 0;
|
|
100
|
+
const maxPagesDefault = SUBSCRIPTIONS.HISTORY_MAX_PAGES;
|
|
101
|
+
const maxPages = Number.isFinite(options.maxPages) ? options.maxPages : maxPagesDefault;
|
|
102
|
+
// Cap page size to the node's api_limit_get_account_history to avoid FC_ASSERT.
|
|
103
|
+
const configuredLimit = typeof chainClient.getApiLimitGetAccountHistory === 'function'
|
|
104
|
+
? chainClient.getApiLimitGetAccountHistory()
|
|
105
|
+
: null;
|
|
106
|
+
const pageLimit = configuredLimit != null
|
|
107
|
+
? Math.min(SUBSCRIPTIONS.HISTORY_LOOKBACK_MAX, configuredLimit)
|
|
108
|
+
: SUBSCRIPTIONS.HISTORY_LOOKBACK_MAX;
|
|
109
|
+
if (configuredLimit != null && configuredLimit < SUBSCRIPTIONS.HISTORY_LOOKBACK_MAX) {
|
|
110
|
+
subscriptionsLogger.warn(`fetchFillHistoryEntries: node api_limit_get_account_history (${configuredLimit}) ` +
|
|
111
|
+
`< HISTORY_LOOKBACK_MAX (${SUBSCRIPTIONS.HISTORY_LOOKBACK_MAX}), capping page size to ${pageLimit}`);
|
|
112
|
+
}
|
|
113
|
+
subscriptionsLogger.debug(`fetchFillHistoryEntries: account=${accountId}, cursor=${cursorHistoryId}, start=${startHistoryId}, maxPages=${maxPages}, pageLimit=${pageLimit}`);
|
|
114
|
+
while (true) {
|
|
115
|
+
const page = await Promise.resolve(fetchPage(accountId, cursorHistoryId, pageLimit, startHistoryId));
|
|
116
|
+
pagesFetched++;
|
|
117
|
+
const pageLen = Array.isArray(page) ? page.length : 0;
|
|
118
|
+
subscriptionsLogger.debug(`fetchFillHistoryEntries: page ${pagesFetched} returned ${pageLen} entries (start=${startHistoryId}, stop=${cursorHistoryId})`);
|
|
119
|
+
if (!Array.isArray(page) || page.length === 0)
|
|
120
|
+
break;
|
|
121
|
+
let allEntriesAtOrBeforeCursor = true;
|
|
122
|
+
let skippedCount = 0;
|
|
123
|
+
for (const entry of page) {
|
|
124
|
+
if (!entry || !entry.id || seenIds.has(entry.id))
|
|
125
|
+
continue;
|
|
126
|
+
seenIds.add(entry.id);
|
|
127
|
+
// Only keep entries strictly newer than the cursor (already-delivered).
|
|
128
|
+
const entryInstance = parseObjectIdInstance(entry.id);
|
|
129
|
+
if (Number.isFinite(cursorInstance) && Number.isFinite(entryInstance) && entryInstance <= cursorInstance) {
|
|
130
|
+
skippedCount++;
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
allEntriesAtOrBeforeCursor = false;
|
|
134
|
+
entries.push(entry);
|
|
135
|
+
}
|
|
136
|
+
if (skippedCount > 0) {
|
|
137
|
+
subscriptionsLogger.debug(`fetchFillHistoryEntries: skipped ${skippedCount} entries at/before cursor (cursor=${cursorHistoryId})`);
|
|
138
|
+
}
|
|
139
|
+
if (page.length < pageLimit) {
|
|
140
|
+
subscriptionsLogger.debug(`fetchFillHistoryEntries: last page (${page.length} < ${pageLimit})`);
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
if (maxPages !== null && pagesFetched >= maxPages) {
|
|
144
|
+
subscriptionsLogger.debug(`fetchFillHistoryEntries: maxPages (${maxPages}) reached`);
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
// Stop if all entries on this page are at or before the cursor.
|
|
148
|
+
if (allEntriesAtOrBeforeCursor)
|
|
149
|
+
break;
|
|
150
|
+
const oldestId = page[page.length - 1]?.id;
|
|
151
|
+
const nextStartHistoryId = decrementObjectId(oldestId);
|
|
152
|
+
if (!oldestId || !nextStartHistoryId || nextStartHistoryId === startHistoryId)
|
|
153
|
+
break;
|
|
154
|
+
startHistoryId = nextStartHistoryId;
|
|
155
|
+
}
|
|
156
|
+
subscriptionsLogger.debug(`fetchFillHistoryEntries: returning ${entries.length} operation(s) across ${pagesFetched} page(s) for ${accountId}`);
|
|
157
|
+
return sortEntriesOldestFirst(entries);
|
|
158
|
+
}
|
|
159
|
+
async function primeLastDeliveredHistoryId(sub) {
|
|
160
|
+
if (!sub?.accountId)
|
|
161
|
+
return SUBSCRIPTIONS.HISTORY_API_OBJECT;
|
|
162
|
+
// btsdex parity: use get_account_history (unfiltered) to find the
|
|
163
|
+
// single most recent history entry. This seeds the cursor past "1.11.0"
|
|
164
|
+
// so fetchFillHistoryEntries can scan from the latest entry forward.
|
|
165
|
+
const fetchAnyPage = getAccountHistoryFetcher();
|
|
166
|
+
try {
|
|
167
|
+
const entries = await Promise.resolve(fetchAnyPage(sub.accountId, SUBSCRIPTIONS.HISTORY_API_OBJECT, 1, SUBSCRIPTIONS.HISTORY_API_OBJECT));
|
|
168
|
+
const latestId = entries?.[0]?.id;
|
|
169
|
+
if (latestId) {
|
|
170
|
+
subscriptionsLogger.info(`primeLastDeliveredHistoryId: resolved to ${latestId} for ${sub.accountName}`);
|
|
171
|
+
return latestId;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
subscriptionsLogger.warn(`primeLastDeliveredHistoryId: get_account_history failed for ${sub.accountName}: ${err.message}`);
|
|
176
|
+
}
|
|
177
|
+
subscriptionsLogger.info(`primeLastDeliveredHistoryId: no history found, using HISTORY_API_OBJECT for ${sub.accountName}`);
|
|
178
|
+
return SUBSCRIPTIONS.HISTORY_API_OBJECT;
|
|
179
|
+
}
|
|
180
|
+
function ensureNoticeSubscription() {
|
|
181
|
+
if (unsubscribeNotice) {
|
|
182
|
+
if (typeof unsubscribeNotice.isActive !== 'function' || unsubscribeNotice.isActive())
|
|
183
|
+
return;
|
|
184
|
+
unsubscribeNotice = null;
|
|
185
|
+
}
|
|
186
|
+
unsubscribeNotice = chainClient.transport.addMessageHandler(handleNotice);
|
|
187
|
+
}
|
|
188
|
+
function removeNoticeSubscription() {
|
|
189
|
+
if (unsubscribeNotice) {
|
|
190
|
+
unsubscribeNotice();
|
|
191
|
+
unsubscribeNotice = null;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Check if a fill object's account_id matches the given account ID.
|
|
196
|
+
* Each fill_order_operation has an `account_id` field identifying
|
|
197
|
+
* the account whose order was filled.
|
|
198
|
+
*/
|
|
199
|
+
function fillMatchesAccount(fill, accountId) {
|
|
200
|
+
const fillAccountId = fill?.op?.[1]?.account_id;
|
|
201
|
+
return fillAccountId === accountId;
|
|
202
|
+
}
|
|
203
|
+
async function handleNotice(params) {
|
|
204
|
+
if (!Array.isArray(params) || params.length < 2) {
|
|
205
|
+
subscriptionsLogger.info('handleNotice: skipping (invalid params)');
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const [callbackId, data] = params;
|
|
209
|
+
if (callbackId !== SUBSCRIBE_CALLBACK_ID)
|
|
210
|
+
return;
|
|
211
|
+
if (!Array.isArray(data) || data.length === 0)
|
|
212
|
+
return;
|
|
213
|
+
// Extract fill objects directly from notice data (mirrors btsdex behavior).
|
|
214
|
+
// The BitShares node sends full 1.11.x operation history objects in the
|
|
215
|
+
// notice when a fill occurs. We pass them straight to callbacks — no
|
|
216
|
+
// history scan, no cursor tracking needed for live fills.
|
|
217
|
+
const fillObjects = [];
|
|
218
|
+
for (const item of data) {
|
|
219
|
+
if (!item || typeof item !== 'object')
|
|
220
|
+
continue;
|
|
221
|
+
const op = item.op;
|
|
222
|
+
if (Array.isArray(op) && op[0] === OP_FILL_ORDER) {
|
|
223
|
+
fillObjects.push({
|
|
224
|
+
type: 'fill',
|
|
225
|
+
op: op,
|
|
226
|
+
block_num: item.block_num,
|
|
227
|
+
trx_in_block: item.trx_in_block,
|
|
228
|
+
id: item.id,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
if (fillObjects.length === 0) {
|
|
233
|
+
// No fills in this notice — scan all active subscriptions to catch
|
|
234
|
+
// up on any fills that may have occurred. Non-fill notices (object
|
|
235
|
+
// changes, statistics updates, etc.) don't carry op data, so we must
|
|
236
|
+
// fall back to history scanning to detect fills.
|
|
237
|
+
//
|
|
238
|
+
// Compute the per-notice max history instance once. Bare object notices
|
|
239
|
+
// (statistics/account/limit-order updates) carry no 1.11.x id, so
|
|
240
|
+
// noticeMaxInstance stays at -1 and the per-subscription cursor check
|
|
241
|
+
// falls through to the coalesced scan path.
|
|
242
|
+
let noticeMaxInstance = -1;
|
|
243
|
+
for (const item of data) {
|
|
244
|
+
if (!item || typeof item !== 'object')
|
|
245
|
+
continue;
|
|
246
|
+
const id = item.id;
|
|
247
|
+
if (typeof id !== 'string' || !id.startsWith('1.11.'))
|
|
248
|
+
continue;
|
|
249
|
+
const inst = parseObjectIdInstance(id);
|
|
250
|
+
if (Number.isFinite(inst) && inst > noticeMaxInstance) {
|
|
251
|
+
noticeMaxInstance = inst;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
const now = Date.now();
|
|
255
|
+
const eligible = [];
|
|
256
|
+
for (const [, sub] of subscriptions) {
|
|
257
|
+
if (!sub.active)
|
|
258
|
+
continue;
|
|
259
|
+
// Skip when the notice carries a 1.11.x id that this sub's cursor
|
|
260
|
+
// has already covered — no new fills to catch up.
|
|
261
|
+
if (noticeMaxInstance !== -1) {
|
|
262
|
+
const subCursorInstance = parseObjectIdInstance(sub.lastDeliveredHistoryId);
|
|
263
|
+
if (Number.isFinite(subCursorInstance) && subCursorInstance >= noticeMaxInstance)
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
eligible.push(sub);
|
|
267
|
+
}
|
|
268
|
+
if (eligible.length === 0)
|
|
269
|
+
return;
|
|
270
|
+
// Coalesce: no-fill notices are just trigger signals. Schedule one
|
|
271
|
+
// history scan per subscription for the coalesce window instead of
|
|
272
|
+
// running one RPC per notice.
|
|
273
|
+
const stampNow = Date.now();
|
|
274
|
+
for (const sub of eligible) {
|
|
275
|
+
// Stamp eligible subs as alive — the notice arrived and a scan
|
|
276
|
+
// will follow. We can't route non-fill objects per-account, so
|
|
277
|
+
// this stamps all eligible subs imprecisely.
|
|
278
|
+
//
|
|
279
|
+
// Coverage gap: if only non-fill notices are arriving (e.g. a
|
|
280
|
+
// statistics-only update for account A), all eligible subs get
|
|
281
|
+
// stamped, masking a per-account fill-stream death for account B.
|
|
282
|
+
// Mitigation: the coalesced processObjects scan (triggered next)
|
|
283
|
+
// fetches fill history per-account via direct RPC, so no fills
|
|
284
|
+
// are actually lost — they're just discovered on the next scan
|
|
285
|
+
// instead of via push notification.
|
|
286
|
+
sub.lastNoticeAt = stampNow;
|
|
287
|
+
const existing = pendingScans.get(sub);
|
|
288
|
+
if (existing) {
|
|
289
|
+
if ((now - existing.lastNoticeAt) < noticeCoalesceMs) {
|
|
290
|
+
existing.lastNoticeAt = now;
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
clearTimeout(existing.timer);
|
|
294
|
+
pendingScans.delete(sub);
|
|
295
|
+
}
|
|
296
|
+
if (noticeCoalesceMs > 0) {
|
|
297
|
+
const entry = { timer: null, lastNoticeAt: now };
|
|
298
|
+
entry.timer = setTimeout(() => {
|
|
299
|
+
pendingScans.delete(sub);
|
|
300
|
+
processObjects(sub, data).catch((err) => {
|
|
301
|
+
subscriptionsLogger.warn(`processObjects (coalesced) error for ${sub.accountName}: ${err?.message}`);
|
|
302
|
+
});
|
|
303
|
+
}, noticeCoalesceMs);
|
|
304
|
+
if (typeof entry.timer.unref === 'function')
|
|
305
|
+
entry.timer.unref();
|
|
306
|
+
pendingScans.set(sub, entry);
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
await processObjects(sub, data);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
subscriptionsLogger.info(`handleNotice: dispatching ${fillObjects.length} fill(s) directly from notice data`);
|
|
315
|
+
// Batch fills per-subscription and dispatch all at once (mirrors btsdex behavior
|
|
316
|
+
// where a single callback receives all fills from one notice).
|
|
317
|
+
for (const [, sub] of subscriptions) {
|
|
318
|
+
if (!sub.active)
|
|
319
|
+
continue;
|
|
320
|
+
const subFills = fillObjects.filter((fill) => fillMatchesAccount(fill, sub.accountId));
|
|
321
|
+
if (subFills.length === 0)
|
|
322
|
+
continue;
|
|
323
|
+
// Compute cursor for this batch but do NOT advance until callbacks succeed.
|
|
324
|
+
// On failure the cursor stays unchanged so the next processObjects scan
|
|
325
|
+
// (triggered by the next notice or reconnect) will re-fetch these fills.
|
|
326
|
+
// Scan ALL notice entries (not just fills) to prevent re-fetching non-fill
|
|
327
|
+
// operations on subsequent processObjects scans. Non-fill ops may have
|
|
328
|
+
// higher IDs than fills in the same block.
|
|
329
|
+
let latestId = null;
|
|
330
|
+
let latestInstance = -1;
|
|
331
|
+
for (const item of data) {
|
|
332
|
+
if (!item || typeof item !== 'object')
|
|
333
|
+
continue;
|
|
334
|
+
const inst = parseObjectIdInstance(item.id);
|
|
335
|
+
if (Number.isFinite(inst) && inst > latestInstance) {
|
|
336
|
+
latestInstance = inst;
|
|
337
|
+
latestId = item.id;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
const failed = [];
|
|
341
|
+
for (const callback of sub.callbacks) {
|
|
342
|
+
try {
|
|
343
|
+
await Promise.resolve(callback(subFills));
|
|
344
|
+
}
|
|
345
|
+
catch (err) {
|
|
346
|
+
subscriptionsLogger.warn(`handleNotice: callback error for ${sub.accountName}: ${err?.message}`);
|
|
347
|
+
failed.push(err);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
// Notice delivered a fill for this account — stamp alive regardless
|
|
351
|
+
// of callback outcome. Callback failure is a processing issue tracked
|
|
352
|
+
// separately (cursor not advanced, onError dispatched).
|
|
353
|
+
sub.lastNoticeAt = Date.now();
|
|
354
|
+
if (failed.length > 0) {
|
|
355
|
+
if (sub.onError) {
|
|
356
|
+
for (const err of failed) {
|
|
357
|
+
try {
|
|
358
|
+
sub.onError(err);
|
|
359
|
+
}
|
|
360
|
+
catch (_) { }
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
// Cursor NOT advanced — retry on next scan.
|
|
364
|
+
}
|
|
365
|
+
else if (latestId && (!sub.lastDeliveredHistoryId || parseObjectIdInstance(latestId) > parseObjectIdInstance(sub.lastDeliveredHistoryId))) {
|
|
366
|
+
sub.lastDeliveredHistoryId = latestId;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
async function processObjects(sub, data, options = {}) {
|
|
371
|
+
if (!data || !Array.isArray(data))
|
|
372
|
+
return;
|
|
373
|
+
const noticeObjectIds = [];
|
|
374
|
+
for (const item of data) {
|
|
375
|
+
if (!item)
|
|
376
|
+
continue;
|
|
377
|
+
const id = typeof item === 'object' ? item.id : item;
|
|
378
|
+
if (typeof id !== 'string')
|
|
379
|
+
continue;
|
|
380
|
+
noticeObjectIds.push(id);
|
|
381
|
+
}
|
|
382
|
+
if (noticeObjectIds.length === 0) {
|
|
383
|
+
subscriptionsLogger.debug(`processObjects: no identifiable object IDs in notice data for ${sub.accountName} (dataLen=${data?.length}, types=${data.map((d) => typeof d).join(',')})`);
|
|
384
|
+
// NOTE: Do NOT return early here. The notice data is just a trigger signal;
|
|
385
|
+
// we must always scan fill history to catch actual fills, because the node
|
|
386
|
+
// may send objects without string `id` fields (e.g. bare account/statistics objects).
|
|
387
|
+
// Fall through to the account fetch + history scan below.
|
|
388
|
+
}
|
|
389
|
+
try {
|
|
390
|
+
// Skip get_full_accounts (heavy RPC) when accountId is already known.
|
|
391
|
+
// All callers (handleNotice, resubscribeEntry, resubscribeAll) either
|
|
392
|
+
// set it during subscribe or refresh it in their preamble.
|
|
393
|
+
let accountId = sub.accountId;
|
|
394
|
+
if (!accountId) {
|
|
395
|
+
const accData = await fetchFullAccountWithRetry(sub, false);
|
|
396
|
+
if (!accData) {
|
|
397
|
+
subscriptionsLogger.warn(`processObjects: get_full_accounts returned no data for ${sub.accountName}`);
|
|
398
|
+
if (options.throwOnError) {
|
|
399
|
+
throw new Error('get_full_accounts returned no account data');
|
|
400
|
+
}
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
accountId = accData.account?.id || sub.accountId;
|
|
404
|
+
if (!accountId) {
|
|
405
|
+
subscriptionsLogger.warn(`processObjects: no account id after fetch for ${sub.accountName}`);
|
|
406
|
+
if (options.throwOnError) {
|
|
407
|
+
throw new Error('get_full_accounts returned no account id');
|
|
408
|
+
}
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
sub.accountId = accountId;
|
|
412
|
+
sub.statisticsId = accData.account?.statistics || sub.statisticsId || null;
|
|
413
|
+
}
|
|
414
|
+
if (!sub.lastDeliveredHistoryId) {
|
|
415
|
+
sub.lastDeliveredHistoryId = await primeLastDeliveredHistoryId(sub);
|
|
416
|
+
subscriptionsLogger.debug(`processObjects: primed lastDeliveredHistoryId=${sub.lastDeliveredHistoryId} for ${sub.accountName}`);
|
|
417
|
+
}
|
|
418
|
+
const history = await fetchFillHistoryEntries(accountId, sub.lastDeliveredHistoryId, options);
|
|
419
|
+
if (history.length === 0) {
|
|
420
|
+
sub.lastNoticeAt = Date.now();
|
|
421
|
+
subscriptionsLogger.debug(`processObjects: no history entries for ${sub.accountName} (cursor=${sub.lastDeliveredHistoryId})`);
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
const historyRange = history.length > 0
|
|
425
|
+
? `${history[0]?.id}..${history[history.length - 1]?.id}`
|
|
426
|
+
: 'empty';
|
|
427
|
+
subscriptionsLogger.debug(`processObjects: ${history.length} history entries for ${sub.accountName} range=${historyRange} cursor=${sub.lastDeliveredHistoryId}`);
|
|
428
|
+
const fills = [];
|
|
429
|
+
for (const entry of history) {
|
|
430
|
+
if (!entry || !entry.op || !entry.id)
|
|
431
|
+
continue;
|
|
432
|
+
const opData = entry.op;
|
|
433
|
+
if (Array.isArray(opData) && opData[0] === OP_FILL_ORDER) {
|
|
434
|
+
fills.push({
|
|
435
|
+
type: 'fill',
|
|
436
|
+
op: opData,
|
|
437
|
+
block_num: entry.block_num,
|
|
438
|
+
trx_in_block: entry.trx_in_block,
|
|
439
|
+
id: entry.id,
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
if (fills.length > 0) {
|
|
444
|
+
const fillIds = fills.map(f => f.id).join(', ');
|
|
445
|
+
const newCursor = history[history.length - 1]?.id || sub.lastDeliveredHistoryId;
|
|
446
|
+
subscriptionsLogger.info(`processObjects: dispatching ${fills.length} fill(s) to ${sub.callbacks.size} callback(s) for ${sub.accountName} cursor=${newCursor} fills=[${fillIds}]`);
|
|
447
|
+
const failed = [];
|
|
448
|
+
for (const callback of sub.callbacks) {
|
|
449
|
+
try {
|
|
450
|
+
await Promise.resolve(callback(fills));
|
|
451
|
+
}
|
|
452
|
+
catch (err) {
|
|
453
|
+
subscriptionsLogger.warn(`processObjects: callback error for ${sub.accountName}: ${err?.message}`);
|
|
454
|
+
failed.push(err);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
if (failed.length > 0) {
|
|
458
|
+
sub.lastNoticeAt = Date.now();
|
|
459
|
+
if (sub.onError) {
|
|
460
|
+
for (const err of failed) {
|
|
461
|
+
try {
|
|
462
|
+
sub.onError(err);
|
|
463
|
+
}
|
|
464
|
+
catch (_) { }
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
if (options.throwOnError) {
|
|
468
|
+
// Do NOT advance cursor on throwOnError failure — the caller
|
|
469
|
+
// (resubscribeEntry/resubscribeAll) will retry and must find
|
|
470
|
+
// the same fills again.
|
|
471
|
+
failed[0].subscriptionErrorReported = true;
|
|
472
|
+
throw failed[0];
|
|
473
|
+
}
|
|
474
|
+
// Non-throwing path (e.g. handleNotice fallback scan): also do NOT
|
|
475
|
+
// advance cursor. The next notice-triggered scan or reconnect will
|
|
476
|
+
// re-fetch these fills, giving callbacks another chance.
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
// All callbacks succeeded — advance cursor past this batch.
|
|
480
|
+
sub.lastDeliveredHistoryId = newCursor;
|
|
481
|
+
sub.lastNoticeAt = Date.now();
|
|
482
|
+
}
|
|
483
|
+
else {
|
|
484
|
+
// No fills in this batch — advance cursor past history to avoid
|
|
485
|
+
// re-scanning non-fill operations on subsequent calls.
|
|
486
|
+
sub.lastDeliveredHistoryId = history[history.length - 1]?.id || sub.lastDeliveredHistoryId;
|
|
487
|
+
sub.lastNoticeAt = Date.now();
|
|
488
|
+
subscriptionsLogger.debug(`processObjects: history had entries but none were FILL_ORDER operations for ${sub.accountName}`);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
catch (err) {
|
|
492
|
+
sub.lastNoticeAt = Date.now();
|
|
493
|
+
subscriptionsLogger.warn(`processObjects: error for ${sub.accountName}: ${err?.message}`);
|
|
494
|
+
if (sub.onError && !err?.subscriptionErrorReported) {
|
|
495
|
+
try {
|
|
496
|
+
sub.onError(err);
|
|
497
|
+
}
|
|
498
|
+
catch (_) { }
|
|
499
|
+
}
|
|
500
|
+
if (options.throwOnError)
|
|
501
|
+
throw err;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
function clearReconnectRetry(entry) {
|
|
505
|
+
if (!entry?.reconnectRetryTimer)
|
|
506
|
+
return;
|
|
507
|
+
clearTimeout(entry.reconnectRetryTimer);
|
|
508
|
+
entry.reconnectRetryTimer = null;
|
|
509
|
+
}
|
|
510
|
+
function scheduleReconnectRetry(entry, err) {
|
|
511
|
+
if (!entry || entry.reconnectRetryTimer || !entry.active || entry.callbacks?.size === 0)
|
|
512
|
+
return;
|
|
513
|
+
entry.reconnectRetryTimer = setTimeout(() => {
|
|
514
|
+
entry.reconnectRetryTimer = null;
|
|
515
|
+
resubscribeEntry(entry, 'retry').catch((retryErr) => {
|
|
516
|
+
subscriptionsLogger.warn(`Failed to resubscribe ${entry.accountName}: ${retryErr.message}`);
|
|
517
|
+
scheduleReconnectRetry(entry, retryErr);
|
|
518
|
+
});
|
|
519
|
+
}, reconnectRetryDelayMs);
|
|
520
|
+
if (typeof entry.reconnectRetryTimer.unref === 'function') {
|
|
521
|
+
entry.reconnectRetryTimer.unref();
|
|
522
|
+
}
|
|
523
|
+
warnSubscription(entry, `scheduled reconnect retry in ${reconnectRetryDelayMs}ms`, err);
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Centralized subscription refresh: set_subscribe_callback then re-subscribe ALL active accounts.
|
|
527
|
+
* cancel_all_subscriptions(false, false) inside set_subscribe_callback clears
|
|
528
|
+
* _subscribed_accounts for every account. Every active entry must be re-subscribed after
|
|
529
|
+
* every call, not just the current one.
|
|
530
|
+
*/
|
|
531
|
+
async function refreshSubscriptions() {
|
|
532
|
+
const failures = [];
|
|
533
|
+
ensureNoticeSubscription();
|
|
534
|
+
await chainClient.db.call('set_subscribe_callback', [
|
|
535
|
+
SUBSCRIBE_CALLBACK_ID,
|
|
536
|
+
false,
|
|
537
|
+
]);
|
|
538
|
+
for (const [, subEntry] of subscriptions) {
|
|
539
|
+
if (!subEntry.active)
|
|
540
|
+
continue;
|
|
541
|
+
try {
|
|
542
|
+
await chainClient.db.get_full_accounts([subEntry.accountName], true);
|
|
543
|
+
}
|
|
544
|
+
catch (err) {
|
|
545
|
+
subscriptionsLogger.warn(`Failed to re-subscribe account after set_subscribe_callback for ${subEntry.accountName}: ${err.message}`);
|
|
546
|
+
failures.push({ entry: subEntry, err });
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
return failures;
|
|
550
|
+
}
|
|
551
|
+
async function resubscribeEntry(entry, reason = 'reconnect') {
|
|
552
|
+
if (!entry?.active)
|
|
553
|
+
return;
|
|
554
|
+
if (entry.reconnecting)
|
|
555
|
+
return;
|
|
556
|
+
entry.reconnecting = true;
|
|
557
|
+
try {
|
|
558
|
+
try {
|
|
559
|
+
const accounts = await chainClient.db.get_full_accounts([entry.accountName], true);
|
|
560
|
+
if (accounts && accounts[0] && accounts[0][1] && accounts[0][1].account) {
|
|
561
|
+
entry.accountId = accounts[0][1].account.id;
|
|
562
|
+
entry.statisticsId = accounts[0][1].account.statistics || null;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
catch (err) {
|
|
566
|
+
subscriptionsLogger.warn(`Failed to refresh account data for ${entry.accountName}: ${err.message}`);
|
|
567
|
+
}
|
|
568
|
+
const refreshFailures = await refreshSubscriptions();
|
|
569
|
+
const entryRefreshFailure = refreshFailures.find((failure) => failure.entry === entry);
|
|
570
|
+
if (entryRefreshFailure)
|
|
571
|
+
throw entryRefreshFailure.err;
|
|
572
|
+
for (const failure of refreshFailures) {
|
|
573
|
+
scheduleReconnectRetry(failure.entry, failure.err);
|
|
574
|
+
}
|
|
575
|
+
await processObjects(entry, [entry.accountId], {
|
|
576
|
+
throwOnError: true,
|
|
577
|
+
});
|
|
578
|
+
clearReconnectRetry(entry);
|
|
579
|
+
subscriptionsLogger.warn(`Subscription restored for ${entry.accountName} (${reason})`);
|
|
580
|
+
}
|
|
581
|
+
finally {
|
|
582
|
+
entry.reconnecting = false;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
function startSubscriptionHealthCheck() {
|
|
586
|
+
const intervalMs = Number.isFinite(SUBSCRIPTIONS.SUBSCRIPTION_HEALTH_CHECK_INTERVAL_MS)
|
|
587
|
+
? Math.max(10000, SUBSCRIPTIONS.SUBSCRIPTION_HEALTH_CHECK_INTERVAL_MS)
|
|
588
|
+
: 60000;
|
|
589
|
+
const silentThresholdMs = Number.isFinite(SUBSCRIPTIONS.SUBSCRIPTION_SILENT_THRESHOLD_MS)
|
|
590
|
+
? Math.max(30000, SUBSCRIPTIONS.SUBSCRIPTION_SILENT_THRESHOLD_MS)
|
|
591
|
+
: 600000;
|
|
592
|
+
if (subscriptionHealthTimer)
|
|
593
|
+
return;
|
|
594
|
+
subscriptionHealthTimer = setInterval(async () => {
|
|
595
|
+
// Re-entrancy guard: if a previous tick is still processing (e.g.
|
|
596
|
+
// resubscribeEntry + catch-up scans take longer than intervalMs),
|
|
597
|
+
// skip this tick rather than running redundant set_subscribe_callback.
|
|
598
|
+
if (healthCheckInProgress)
|
|
599
|
+
return;
|
|
600
|
+
healthCheckInProgress = true;
|
|
601
|
+
try {
|
|
602
|
+
const now = Date.now();
|
|
603
|
+
const stale = [];
|
|
604
|
+
for (const [, entry] of subscriptions) {
|
|
605
|
+
if (!entry.active)
|
|
606
|
+
continue;
|
|
607
|
+
if (entry.reconnecting)
|
|
608
|
+
continue;
|
|
609
|
+
const elapsed = now - entry.lastNoticeAt;
|
|
610
|
+
if (elapsed >= silentThresholdMs) {
|
|
611
|
+
stale.push({ entry, elapsed });
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
if (stale.length === 0)
|
|
615
|
+
return;
|
|
616
|
+
// Sort so the longest-stale account drives the resubscribe.
|
|
617
|
+
stale.sort((a, b) => b.elapsed - a.elapsed);
|
|
618
|
+
// All accounts share one WebSocket subscription feed. If one is
|
|
619
|
+
// stale the entire feed is dead — resubscribe once and catch up
|
|
620
|
+
// all stale entries rather than triggering N redundant resubscribes.
|
|
621
|
+
subscriptionsLogger.warn(`Subscription health: ${stale.length} account(s) stale; resubscribing via ${stale[0].entry.accountName} ` +
|
|
622
|
+
`(oldest=${Math.round(stale[0].elapsed / 1000)}s, threshold=${Math.round(silentThresholdMs / 1000)}s)`);
|
|
623
|
+
const firstEntry = stale[0].entry;
|
|
624
|
+
try {
|
|
625
|
+
await resubscribeEntry(firstEntry, 'healthcheck');
|
|
626
|
+
}
|
|
627
|
+
catch (err) {
|
|
628
|
+
subscriptionsLogger.warn(`Subscription health: resubscribe failed for ${firstEntry.accountName}: ${err.message}`);
|
|
629
|
+
}
|
|
630
|
+
// Catch up remaining stale entries with processObjects (the
|
|
631
|
+
// subscription is already re-established for all accounts by
|
|
632
|
+
// refreshSubscriptions inside resubscribeEntry).
|
|
633
|
+
for (let i = 1; i < stale.length; i++) {
|
|
634
|
+
const { entry } = stale[i];
|
|
635
|
+
if (entry.reconnecting)
|
|
636
|
+
continue;
|
|
637
|
+
entry.reconnecting = true;
|
|
638
|
+
try {
|
|
639
|
+
await processObjects(entry, [entry.accountId], { throwOnError: true });
|
|
640
|
+
clearReconnectRetry(entry);
|
|
641
|
+
subscriptionsLogger.warn(`Subscription restored for ${entry.accountName} (healthcheck)`);
|
|
642
|
+
}
|
|
643
|
+
catch (err) {
|
|
644
|
+
subscriptionsLogger.warn(`Subscription health: catch-up scan failed for ${entry.accountName}: ${err.message}`);
|
|
645
|
+
scheduleReconnectRetry(entry, err);
|
|
646
|
+
}
|
|
647
|
+
finally {
|
|
648
|
+
entry.reconnecting = false;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
finally {
|
|
653
|
+
healthCheckInProgress = false;
|
|
654
|
+
}
|
|
655
|
+
}, intervalMs);
|
|
656
|
+
if (typeof subscriptionHealthTimer.unref === 'function') {
|
|
657
|
+
subscriptionHealthTimer.unref();
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
function stopSubscriptionHealthCheck() {
|
|
661
|
+
if (subscriptionHealthTimer) {
|
|
662
|
+
clearInterval(subscriptionHealthTimer);
|
|
663
|
+
subscriptionHealthTimer = null;
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
async function subscribe(accountName, callback, onError = null) {
|
|
667
|
+
if (!accountName || typeof accountName !== 'string') {
|
|
668
|
+
throw new Error('accountName is required');
|
|
669
|
+
}
|
|
670
|
+
if (typeof callback !== 'function') {
|
|
671
|
+
throw new Error('callback function is required');
|
|
672
|
+
}
|
|
673
|
+
let entry = subscriptions.get(accountName);
|
|
674
|
+
const createdEntry = !entry;
|
|
675
|
+
if (!entry) {
|
|
676
|
+
entry = {
|
|
677
|
+
accountName,
|
|
678
|
+
accountId: null,
|
|
679
|
+
statisticsId: null,
|
|
680
|
+
lastDeliveredHistoryId: SUBSCRIPTIONS.HISTORY_API_OBJECT,
|
|
681
|
+
lastNoticeAt: Date.now(), // cold-start: watchdog won't fire for one full threshold window
|
|
682
|
+
active: false,
|
|
683
|
+
callbacks: new Set(),
|
|
684
|
+
onError: null,
|
|
685
|
+
reconnectRetryTimer: null,
|
|
686
|
+
reconnecting: false,
|
|
687
|
+
};
|
|
688
|
+
subscriptions.set(accountName, entry);
|
|
689
|
+
// Add callback BEFORE first await so a rollback unsubscribe()
|
|
690
|
+
// during the async work can properly find and remove it,
|
|
691
|
+
// keeping callbacks consistent and avoiding orphaned entries.
|
|
692
|
+
entry.callbacks.add(callback);
|
|
693
|
+
if (onError)
|
|
694
|
+
entry.onError = onError;
|
|
695
|
+
const accounts = await chainClient.db.get_full_accounts([accountName], true);
|
|
696
|
+
// Detect a rollback unsubscribe() that fired during the await:
|
|
697
|
+
// the entry is gone from the Map, so the native subscription was
|
|
698
|
+
// already torn down by the caller. Abort cleanly without
|
|
699
|
+
// re-priming or registering a server-side subscription — otherwise
|
|
700
|
+
// the local entry would be orphaned (still in memory, not in Map)
|
|
701
|
+
// and handleNotice() would never reach its callbacks.
|
|
702
|
+
if (!subscriptions.has(accountName)) {
|
|
703
|
+
return () => { };
|
|
704
|
+
}
|
|
705
|
+
if (accounts && accounts[0] && accounts[0][1] && accounts[0][1].account) {
|
|
706
|
+
entry.accountId = accounts[0][1].account.id;
|
|
707
|
+
entry.statisticsId = accounts[0][1].account.statistics || null;
|
|
708
|
+
}
|
|
709
|
+
if (!entry.accountId) {
|
|
710
|
+
subscriptions.delete(accountName);
|
|
711
|
+
throw new Error(`Could not resolve subscribed account: ${accountName}`);
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
else {
|
|
715
|
+
entry.callbacks.add(callback);
|
|
716
|
+
if (onError)
|
|
717
|
+
entry.onError = onError;
|
|
718
|
+
}
|
|
719
|
+
if (createdEntry) {
|
|
720
|
+
try {
|
|
721
|
+
// Prime the cursor BEFORE remote activation. The cursor is
|
|
722
|
+
// decremented so that the next scan re-fetches the primed fill,
|
|
723
|
+
// ensuring no fills are lost between prime and subscribe.
|
|
724
|
+
const latestFillId = await primeLastDeliveredHistoryId(entry);
|
|
725
|
+
if (!subscriptions.has(accountName)) {
|
|
726
|
+
// Rollback during prime — entry is gone. Abort without
|
|
727
|
+
// activating or calling refreshSubscriptions.
|
|
728
|
+
return () => { };
|
|
729
|
+
}
|
|
730
|
+
entry.lastDeliveredHistoryId = latestFillId
|
|
731
|
+
? (decrementObjectId(latestFillId) || latestFillId)
|
|
732
|
+
: SUBSCRIPTIONS.HISTORY_API_OBJECT;
|
|
733
|
+
entry.active = !!entry.accountId;
|
|
734
|
+
const refreshFailures = await refreshSubscriptions();
|
|
735
|
+
if (!subscriptions.has(accountName)) {
|
|
736
|
+
// Rollback during refreshSubscriptions — entry is gone.
|
|
737
|
+
// Abort. The server-side set_subscribe_callback was already
|
|
738
|
+
// called (side effect of refreshSubscriptions), but the
|
|
739
|
+
// local entry is no longer in the Map so handleNotice()
|
|
740
|
+
// cannot dispatch to its callbacks. The orphaned callbacks
|
|
741
|
+
// become unreachable and will be GC'd on process exit.
|
|
742
|
+
return () => { };
|
|
743
|
+
}
|
|
744
|
+
const entryRefreshFailure = refreshFailures.find((failure) => failure.entry === entry);
|
|
745
|
+
if (entryRefreshFailure)
|
|
746
|
+
throw entryRefreshFailure.err;
|
|
747
|
+
startSubscriptionHealthCheck();
|
|
748
|
+
for (const failure of refreshFailures) {
|
|
749
|
+
scheduleReconnectRetry(failure.entry, failure.err);
|
|
750
|
+
}
|
|
751
|
+
// NOTE: No initial catch-up scan here — matching main+btsdex behavior.
|
|
752
|
+
// The startup sync (synchronizeWithChain) handles all fills from downtime.
|
|
753
|
+
// processObjects is called on reconnect (resubscribeEntry/resubscribeAll)
|
|
754
|
+
// to catch fills missed during disconnect, at which point the grid is loaded.
|
|
755
|
+
}
|
|
756
|
+
catch (err) {
|
|
757
|
+
// Only clean up if WE still own the entry. If a rollback already
|
|
758
|
+
// deleted it from the Map during the await that threw, the
|
|
759
|
+
// unsubscribe() rollback path is responsible for state — touching
|
|
760
|
+
// it here would corrupt the next subscribe's accounting.
|
|
761
|
+
if (subscriptions.has(accountName)) {
|
|
762
|
+
entry.callbacks.delete(callback);
|
|
763
|
+
if (entry.onError === onError) {
|
|
764
|
+
entry.onError = null;
|
|
765
|
+
}
|
|
766
|
+
if (entry.callbacks.size === 0) {
|
|
767
|
+
entry.active = false;
|
|
768
|
+
subscriptions.delete(accountName);
|
|
769
|
+
if (subscriptions.size === 0) {
|
|
770
|
+
stopSubscriptionHealthCheck();
|
|
771
|
+
removeNoticeSubscription();
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
throw new Error(`Failed to register subscription callback: ${err.message}`);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
return () => unsubscribe(accountName, callback);
|
|
779
|
+
}
|
|
780
|
+
async function unsubscribe(accountName, callback) {
|
|
781
|
+
const entry = subscriptions.get(accountName);
|
|
782
|
+
if (!entry)
|
|
783
|
+
return;
|
|
784
|
+
if (callback) {
|
|
785
|
+
entry.callbacks.delete(callback);
|
|
786
|
+
}
|
|
787
|
+
else {
|
|
788
|
+
entry.callbacks.clear();
|
|
789
|
+
}
|
|
790
|
+
if (entry.callbacks.size === 0) {
|
|
791
|
+
entry.active = false;
|
|
792
|
+
clearReconnectRetry(entry);
|
|
793
|
+
const pending = pendingScans.get(entry);
|
|
794
|
+
if (pending) {
|
|
795
|
+
if (pending.timer)
|
|
796
|
+
clearTimeout(pending.timer);
|
|
797
|
+
pendingScans.delete(entry);
|
|
798
|
+
}
|
|
799
|
+
subscriptions.delete(accountName);
|
|
800
|
+
if (subscriptions.size === 0) {
|
|
801
|
+
stopSubscriptionHealthCheck();
|
|
802
|
+
removeNoticeSubscription();
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
async function resubscribeAll() {
|
|
807
|
+
// Drop any coalesced scans scheduled before the reconnect. They reference
|
|
808
|
+
// a pre-reconnect cursor and would race with the catch-up scan below.
|
|
809
|
+
for (const [, pending] of pendingScans) {
|
|
810
|
+
if (pending.timer)
|
|
811
|
+
clearTimeout(pending.timer);
|
|
812
|
+
}
|
|
813
|
+
pendingScans.clear();
|
|
814
|
+
// Refresh account data for every active entry first (before any RPC calls
|
|
815
|
+
// that might race with each other on the same connection).
|
|
816
|
+
const refreshTasks = [];
|
|
817
|
+
for (const [, entry] of subscriptions) {
|
|
818
|
+
if (!entry.active)
|
|
819
|
+
continue;
|
|
820
|
+
refreshTasks.push(chainClient.db.get_full_accounts([entry.accountName], true).then((accounts) => {
|
|
821
|
+
if (accounts && accounts[0] && accounts[0][1] && accounts[0][1].account) {
|
|
822
|
+
entry.accountId = accounts[0][1].account.id;
|
|
823
|
+
entry.statisticsId = accounts[0][1].account.statistics || null;
|
|
824
|
+
}
|
|
825
|
+
}).catch((err) => {
|
|
826
|
+
subscriptionsLogger.warn(`Failed to refresh account data for ${entry.accountName}: ${err.message}`);
|
|
827
|
+
}));
|
|
828
|
+
}
|
|
829
|
+
await Promise.all(refreshTasks);
|
|
830
|
+
// Centralized subscription setup — one set_subscribe_callback + re-subscribe all.
|
|
831
|
+
const refreshFailures = await refreshSubscriptions();
|
|
832
|
+
const refreshFailureEntries = new Set(refreshFailures.map((failure) => failure.entry));
|
|
833
|
+
for (const failure of refreshFailures) {
|
|
834
|
+
scheduleReconnectRetry(failure.entry, failure.err);
|
|
835
|
+
}
|
|
836
|
+
// Catch-up scan for each entry (parallelized for multi-account setups).
|
|
837
|
+
const scanTasks = [];
|
|
838
|
+
for (const [, entry] of subscriptions) {
|
|
839
|
+
if (!entry.active)
|
|
840
|
+
continue;
|
|
841
|
+
if (refreshFailureEntries.has(entry))
|
|
842
|
+
continue;
|
|
843
|
+
scanTasks.push(processObjects(entry, [entry.accountId], { throwOnError: true })
|
|
844
|
+
.then(() => clearReconnectRetry(entry))
|
|
845
|
+
.catch((err) => {
|
|
846
|
+
subscriptionsLogger.warn(`Failed to resubscribe ${entry.accountName}: ${err.message}`);
|
|
847
|
+
scheduleReconnectRetry(entry, err);
|
|
848
|
+
}));
|
|
849
|
+
}
|
|
850
|
+
await Promise.all(scanTasks);
|
|
851
|
+
}
|
|
852
|
+
async function onReconnect() {
|
|
853
|
+
await resubscribeAll();
|
|
854
|
+
}
|
|
855
|
+
return {
|
|
856
|
+
subscribe,
|
|
857
|
+
unsubscribe,
|
|
858
|
+
onReconnect,
|
|
859
|
+
resubscribeAll,
|
|
860
|
+
removeNoticeSubscription,
|
|
861
|
+
getSubscriptions: () => new Map(subscriptions),
|
|
862
|
+
};
|
|
863
|
+
}
|
|
864
|
+
module.exports = { createSubscriptionManager };
|
|
865
|
+
//# sourceMappingURL=subscriptions.js.map
|