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,1095 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* modules/chain_keys.ts - Authentication and Key Management
|
|
4
|
+
*
|
|
5
|
+
* Secure storage and management of BitShares private keys.
|
|
6
|
+
* Provides authentication, key storage, and transaction signing capabilities.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Master password authentication with derived vault-key verification
|
|
10
|
+
* - AES-256-GCM encryption with random salt and IV
|
|
11
|
+
* - Private key retrieval for transaction signing
|
|
12
|
+
* - Interactive CLI for key management (add/modify/remove)
|
|
13
|
+
* - Daemon readiness checking
|
|
14
|
+
*
|
|
15
|
+
* Storage: profiles/keys.json (gitignored, never committed)
|
|
16
|
+
*
|
|
17
|
+
* Supported key formats:
|
|
18
|
+
* - WIF (Wallet Import Format): 51-52 character Base58Check encoded
|
|
19
|
+
* - PVT_K1_* style keys used by some Graphene chains
|
|
20
|
+
* - Raw 64-character hexadecimal private keys
|
|
21
|
+
*
|
|
22
|
+
* Security: Master password never stored; only a derived vault key is kept in memory.
|
|
23
|
+
* Legacy SHA-256 password hashes are supported only to migrate existing vaults.
|
|
24
|
+
* All newly written private keys use the v2 vault format.
|
|
25
|
+
*
|
|
26
|
+
* ===============================================================================
|
|
27
|
+
* EXPORTS (13 functions + 1 error class)
|
|
28
|
+
* ===============================================================================
|
|
29
|
+
*
|
|
30
|
+
* AUTHENTICATION (1 function)
|
|
31
|
+
* 1. authenticate() - Authenticate and return a derived vault secret (async)
|
|
32
|
+
* Prompts user for password, verifies vault metadata
|
|
33
|
+
* Throws MasterPasswordError on failure
|
|
34
|
+
*
|
|
35
|
+
* KEY MANAGEMENT (3 functions)
|
|
36
|
+
* 2. getPrivateKey(accountName, vaultSecret) - Get private key for account
|
|
37
|
+
* Returns decrypted private key string
|
|
38
|
+
* Throws Error if account not found
|
|
39
|
+
*
|
|
40
|
+
* 3. main() - Interactive CLI for key management (async)
|
|
41
|
+
* Add/modify/remove keys from storage
|
|
42
|
+
* Re-encrypts entire key store
|
|
43
|
+
*
|
|
44
|
+
* 4. validatePrivateKey(key) - Validate private key format
|
|
45
|
+
*
|
|
46
|
+
* CRYPTO HELPERS (7 functions)
|
|
47
|
+
* 5. encrypt(text, secret) - AES-256-GCM encryption
|
|
48
|
+
* 6. decrypt(encryptedHex, secret) - AES-256-GCM decryption
|
|
49
|
+
* 7. deriveVaultKey(password, vaultSalt) - Derive the session vault key
|
|
50
|
+
* 8. deriveSessionSecret(vaultSecret, sessionSalt) - Derive a session-only signing key
|
|
51
|
+
* 9. loadAccounts() - Load accounts from keys.json
|
|
52
|
+
* 10. saveAccounts(data) - Save accounts to keys.json
|
|
53
|
+
* 11. createVaultSecret(...) - Build a serializable derived secret object
|
|
54
|
+
*
|
|
55
|
+
* DAEMON (5 functions)
|
|
56
|
+
* 10. isDaemonReady() - Check if credential daemon is ready
|
|
57
|
+
* 11. isDaemonResponsive() - Check if daemon is responsive
|
|
58
|
+
* 12. waitForDaemon(timeoutMs) - Wait for daemon to become ready (async)
|
|
59
|
+
* 13. probeAccountInDaemon(accountName) - Probe daemon for account (async)
|
|
60
|
+
* 14. pingDaemon(accountName) - Lightweight daemon health check (async)
|
|
61
|
+
*
|
|
62
|
+
* ERROR HANDLING (1 error class)
|
|
63
|
+
* 14. MasterPasswordError - Thrown when authentication fails
|
|
64
|
+
*
|
|
65
|
+
* ===============================================================================
|
|
66
|
+
*
|
|
67
|
+
* KEY STORAGE STRUCTURE (profiles/keys.json):
|
|
68
|
+
* {
|
|
69
|
+
* "vaultVersion": 2,
|
|
70
|
+
* "vaultSalt": "hex-salt",
|
|
71
|
+
* "vaultVerifier": "hex-hmac",
|
|
72
|
+
* "accounts": {
|
|
73
|
+
* "accountName": "v2:recordSalt:iv:authTag:ciphertext"
|
|
74
|
+
* }
|
|
75
|
+
* }
|
|
76
|
+
*
|
|
77
|
+
* ENCRYPTION PROCESS:
|
|
78
|
+
* 1. Generate random vault salt (16 bytes) and derive a vault key with scrypt
|
|
79
|
+
* 2. Derive a per-record key from the vault key with HKDF and a record salt
|
|
80
|
+
* 3. Encrypt private key with AES-256-GCM and a 12-byte IV
|
|
81
|
+
* 4. Store: v2:recordSalt:iv:authTag:ciphertext
|
|
82
|
+
*
|
|
83
|
+
* ===============================================================================
|
|
84
|
+
*/
|
|
85
|
+
const { randomBytes, hkdfSync, scryptSync, createHmac, timingSafeEqual, createCipheriv, createDecipheriv, } = require('./crypto/sync');
|
|
86
|
+
const { path } = require('./path_api');
|
|
87
|
+
const { readInput, readPassword, sleep } = require('./order/utils/system');
|
|
88
|
+
let _net;
|
|
89
|
+
function getNet() {
|
|
90
|
+
if (_net === undefined) {
|
|
91
|
+
try {
|
|
92
|
+
_net = require('net');
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
_net = null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (!_net) {
|
|
99
|
+
throw new Error('Unix socket IPC not available in this environment');
|
|
100
|
+
}
|
|
101
|
+
return _net;
|
|
102
|
+
}
|
|
103
|
+
const { TIMING, CREDENTIAL_PROMPTS } = require('./constants');
|
|
104
|
+
const { PATHS } = require('./paths');
|
|
105
|
+
const { getCredentialReadyFilePath, getCredentialSocketPath, assertPrivatePathSecurity, } = require('./credential_runtime');
|
|
106
|
+
const Logger = require('./logger');
|
|
107
|
+
const { getStorage } = require('./storage');
|
|
108
|
+
const storage = getStorage();
|
|
109
|
+
const { ensureDir, safeUnlink } = require('./utils/fs_utils');
|
|
110
|
+
const { resolvePrivateKey: resolveAuthKey } = require('./authority_resolver');
|
|
111
|
+
const chainKeysLogger = new Logger('chain-keys');
|
|
112
|
+
const VAULT_VERSION = 2;
|
|
113
|
+
const VAULT_SALT_BYTES = 16;
|
|
114
|
+
const VAULT_RECORD_SALT_BYTES = 16;
|
|
115
|
+
const VAULT_IV_BYTES = 12;
|
|
116
|
+
const VAULT_KEY_BYTES = 32;
|
|
117
|
+
const VAULT_SCRYPT_PARAMS = Object.freeze({
|
|
118
|
+
N: 2 ** 17,
|
|
119
|
+
r: 8,
|
|
120
|
+
p: 1,
|
|
121
|
+
// 128 * N * r bytes plus headroom for Node/OpenSSL overhead.
|
|
122
|
+
maxmem: 256 * 1024 * 1024,
|
|
123
|
+
});
|
|
124
|
+
const VAULT_RECORD_INFO = Buffer.from('dexbot2:v2:record-key', 'utf8');
|
|
125
|
+
const VAULT_SESSION_INFO = Buffer.from('dexbot2:v2:session-key', 'utf8');
|
|
126
|
+
const VAULT_VERIFIER_LABEL = 'dexbot2:v2:verifier';
|
|
127
|
+
const VAULT_SECRET_KIND = 'dexbot-vault-secret';
|
|
128
|
+
const VAULT_SESSION_SECRET_KIND = 'dexbot-session-secret';
|
|
129
|
+
const VAULT_DAEMON_SIGNING_TOKEN_KIND = 'dexbot-daemon-signing-token';
|
|
130
|
+
const { Config } = require('./config');
|
|
131
|
+
// Profiles key file (ignored) only
|
|
132
|
+
const PROFILES_KEYS_FILE = Config.DEXBOT_KEYS_FILE
|
|
133
|
+
? path.resolve(Config.DEXBOT_KEYS_FILE)
|
|
134
|
+
: PATHS.PROFILES.KEYS_JSON();
|
|
135
|
+
/**
|
|
136
|
+
* Ensures that the profiles/keys directory exists.
|
|
137
|
+
* @private
|
|
138
|
+
*/
|
|
139
|
+
function ensureProfilesKeysDirectory() {
|
|
140
|
+
const dir = path.dirname(PROFILES_KEYS_FILE);
|
|
141
|
+
ensureDir(dir);
|
|
142
|
+
}
|
|
143
|
+
function toBuffer(value, encoding = 'hex') {
|
|
144
|
+
if (Buffer.isBuffer(value)) {
|
|
145
|
+
return Buffer.from(value);
|
|
146
|
+
}
|
|
147
|
+
if (typeof value === 'string' && value.length > 0) {
|
|
148
|
+
return Buffer.from(value, encoding);
|
|
149
|
+
}
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
function isVaultSecret(value) {
|
|
153
|
+
return !!(value && typeof value === 'object' && value.kind === VAULT_SECRET_KIND);
|
|
154
|
+
}
|
|
155
|
+
function resolveVaultKey(secret) {
|
|
156
|
+
if (!secret)
|
|
157
|
+
return null;
|
|
158
|
+
if (Buffer.isBuffer(secret)) {
|
|
159
|
+
return Buffer.from(secret);
|
|
160
|
+
}
|
|
161
|
+
if (isVaultSecret(secret) && typeof secret.vaultKeyHex === 'string') {
|
|
162
|
+
return toBuffer(secret.vaultKeyHex);
|
|
163
|
+
}
|
|
164
|
+
if (typeof secret === 'object' && typeof secret.vaultKeyHex === 'string') {
|
|
165
|
+
return toBuffer(secret.vaultKeyHex);
|
|
166
|
+
}
|
|
167
|
+
if (typeof secret === 'object' && Buffer.isBuffer(secret.vaultKey)) {
|
|
168
|
+
return Buffer.from(secret.vaultKey);
|
|
169
|
+
}
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
function createVaultSecret(vaultKey, extra = {}) {
|
|
173
|
+
const keyBuffer = resolveVaultKey(vaultKey);
|
|
174
|
+
if (!keyBuffer) {
|
|
175
|
+
throw new Error('Vault secret requires a derived key');
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
kind: VAULT_SECRET_KIND,
|
|
179
|
+
version: extra.version || VAULT_VERSION,
|
|
180
|
+
vaultKeyHex: keyBuffer.toString('hex'),
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
function createSessionSecret(vaultKey, sessionSalt = randomBytes(VAULT_SALT_BYTES)) {
|
|
184
|
+
const keyBuffer = resolveVaultKey(vaultKey);
|
|
185
|
+
const saltBuffer = toBuffer(sessionSalt);
|
|
186
|
+
if (!keyBuffer || !saltBuffer) {
|
|
187
|
+
throw new Error('Vault secret and session salt are required');
|
|
188
|
+
}
|
|
189
|
+
const sessionKey = Buffer.from(hkdfSync('sha256', keyBuffer, saltBuffer, VAULT_SESSION_INFO, VAULT_KEY_BYTES));
|
|
190
|
+
return {
|
|
191
|
+
kind: VAULT_SESSION_SECRET_KIND,
|
|
192
|
+
version: VAULT_VERSION,
|
|
193
|
+
sessionSaltHex: saltBuffer.toString('hex'),
|
|
194
|
+
vaultKeyHex: sessionKey.toString('hex'),
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
function createDaemonSigningToken(accountName, options = {}) {
|
|
198
|
+
if (!accountName || typeof accountName !== 'string') {
|
|
199
|
+
throw new Error('accountName is required for daemon signing');
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
kind: VAULT_DAEMON_SIGNING_TOKEN_KIND,
|
|
203
|
+
accountName,
|
|
204
|
+
socketPath: options.socketPath || getCredentialSocketPath(options),
|
|
205
|
+
sessionId: options.sessionId || null,
|
|
206
|
+
botHmacSecret: options.botHmacSecret || null,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
function isDaemonSigningToken(value) {
|
|
210
|
+
return !!(value && typeof value === 'object' && value.kind === VAULT_DAEMON_SIGNING_TOKEN_KIND && typeof value.accountName === 'string');
|
|
211
|
+
}
|
|
212
|
+
function deriveVaultKey(password, vaultSalt) {
|
|
213
|
+
const saltBuffer = toBuffer(vaultSalt) || randomBytes(VAULT_SALT_BYTES);
|
|
214
|
+
return scryptSync(password, saltBuffer, VAULT_KEY_BYTES, VAULT_SCRYPT_PARAMS);
|
|
215
|
+
}
|
|
216
|
+
function deriveRecordKey(vaultKey, recordSalt) {
|
|
217
|
+
const keyBuffer = resolveVaultKey(vaultKey);
|
|
218
|
+
const saltBuffer = toBuffer(recordSalt);
|
|
219
|
+
if (!keyBuffer || !saltBuffer) {
|
|
220
|
+
throw new Error('Vault key and record salt are required');
|
|
221
|
+
}
|
|
222
|
+
return Buffer.from(hkdfSync('sha256', keyBuffer, saltBuffer, VAULT_RECORD_INFO, VAULT_KEY_BYTES));
|
|
223
|
+
}
|
|
224
|
+
function createVaultVerifier(vaultKey) {
|
|
225
|
+
const keyBuffer = resolveVaultKey(vaultKey);
|
|
226
|
+
if (!keyBuffer) {
|
|
227
|
+
throw new Error('Vault key is required');
|
|
228
|
+
}
|
|
229
|
+
return createHmac('sha256', keyBuffer).update(VAULT_VERIFIER_LABEL).digest('hex');
|
|
230
|
+
}
|
|
231
|
+
function timingSafeEqualHex(leftHex, rightHex) {
|
|
232
|
+
if (typeof leftHex !== 'string' || typeof rightHex !== 'string' || leftHex.length !== rightHex.length) {
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
const left = Buffer.from(leftHex, 'hex');
|
|
236
|
+
const right = Buffer.from(rightHex, 'hex');
|
|
237
|
+
if (left.length !== right.length) {
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
return timingSafeEqual(left, right);
|
|
241
|
+
}
|
|
242
|
+
function normalizeAccountsData(data = {}) {
|
|
243
|
+
const accountsSource = data.accounts && typeof data.accounts === 'object'
|
|
244
|
+
? data.accounts
|
|
245
|
+
: {};
|
|
246
|
+
return {
|
|
247
|
+
vaultVersion: Number(data.vaultVersion) || 0,
|
|
248
|
+
vaultSalt: typeof data.vaultSalt === 'string' ? data.vaultSalt : '',
|
|
249
|
+
vaultVerifier: typeof data.vaultVerifier === 'string' ? data.vaultVerifier : '',
|
|
250
|
+
masterPasswordHash: typeof data.masterPasswordHash === 'string' ? data.masterPasswordHash : '',
|
|
251
|
+
accounts: accountsSource,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
function hasModernVault(accountsData) {
|
|
255
|
+
return !!(accountsData
|
|
256
|
+
&& accountsData.vaultVersion === VAULT_VERSION
|
|
257
|
+
&& typeof accountsData.vaultSalt === 'string'
|
|
258
|
+
&& accountsData.vaultSalt.length > 0
|
|
259
|
+
&& typeof accountsData.vaultVerifier === 'string'
|
|
260
|
+
&& accountsData.vaultVerifier.length > 0);
|
|
261
|
+
}
|
|
262
|
+
function deriveModernSecretFromPassword(password, accountsData) {
|
|
263
|
+
if (!hasModernVault(accountsData)) {
|
|
264
|
+
throw new Error('Vault metadata missing');
|
|
265
|
+
}
|
|
266
|
+
const vaultSalt = toBuffer(accountsData.vaultSalt);
|
|
267
|
+
const vaultKey = deriveVaultKey(password, vaultSalt);
|
|
268
|
+
return createVaultSecret(vaultKey);
|
|
269
|
+
}
|
|
270
|
+
function verifyModernPassword(password, accountsData) {
|
|
271
|
+
if (!hasModernVault(accountsData)) {
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
const secret = deriveModernSecretFromPassword(password, accountsData);
|
|
275
|
+
return timingSafeEqualHex(createVaultVerifier(secret), accountsData.vaultVerifier);
|
|
276
|
+
}
|
|
277
|
+
function isVersionedEncryptedPayload(encrypted) {
|
|
278
|
+
return String(encrypted || '').startsWith('v2:');
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Encrypt text using the v2 AES-256-GCM vault format.
|
|
282
|
+
* @param {string} text - Plain text to encrypt
|
|
283
|
+
* @param {Object|Buffer} secret - Derived vault secret
|
|
284
|
+
* @returns {string} Encrypted data as hex string
|
|
285
|
+
*/
|
|
286
|
+
function encrypt(text, secret) {
|
|
287
|
+
const vaultKey = resolveVaultKey(secret);
|
|
288
|
+
if (!vaultKey) {
|
|
289
|
+
throw new Error('A derived vault secret is required to encrypt v2 key data');
|
|
290
|
+
}
|
|
291
|
+
const salt = randomBytes(VAULT_RECORD_SALT_BYTES);
|
|
292
|
+
const key = deriveRecordKey(vaultKey, salt);
|
|
293
|
+
const iv = randomBytes(VAULT_IV_BYTES);
|
|
294
|
+
const cipher = createCipheriv('aes-256-gcm', key, iv);
|
|
295
|
+
let encrypted = cipher.update(text, 'utf8', 'hex');
|
|
296
|
+
encrypted += cipher.final('hex');
|
|
297
|
+
const authTag = cipher.getAuthTag();
|
|
298
|
+
return 'v2:' + salt.toString('hex') + ':' + iv.toString('hex') + ':' + authTag.toString('hex') + ':' + encrypted;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Decrypt text encrypted with the encrypt() function.
|
|
302
|
+
* @param {string} encrypted - Colon-separated encrypted data
|
|
303
|
+
* @param {Object|Buffer} secret - Derived vault secret
|
|
304
|
+
* @returns {string} Decrypted plain text
|
|
305
|
+
* @throws {Error} If decryption fails (wrong password or corrupted data)
|
|
306
|
+
*/
|
|
307
|
+
function decrypt(encrypted, secret) {
|
|
308
|
+
const parts = String(encrypted || '').split(':');
|
|
309
|
+
if (parts.length < 4) {
|
|
310
|
+
throw new Error('Invalid encrypted payload');
|
|
311
|
+
}
|
|
312
|
+
const isVersioned = parts.length === 5 && parts[0] === 'v2';
|
|
313
|
+
if (!isVersioned && parts.length !== 4) {
|
|
314
|
+
throw new Error('Unsupported encrypted payload version');
|
|
315
|
+
}
|
|
316
|
+
const saltIndex = isVersioned ? 1 : 0;
|
|
317
|
+
const ivIndex = isVersioned ? 2 : 1;
|
|
318
|
+
const authTagIndex = isVersioned ? 3 : 2;
|
|
319
|
+
const payloadIndex = isVersioned ? 4 : 3;
|
|
320
|
+
const salt = toBuffer(parts[saltIndex]);
|
|
321
|
+
const iv = toBuffer(parts[ivIndex]);
|
|
322
|
+
const authTag = toBuffer(parts[authTagIndex]);
|
|
323
|
+
const encryptedText = parts[payloadIndex];
|
|
324
|
+
if (!salt || !iv || !authTag || typeof encryptedText !== 'string') {
|
|
325
|
+
throw new Error('Invalid encrypted payload');
|
|
326
|
+
}
|
|
327
|
+
if (!isVersioned) {
|
|
328
|
+
throw new Error('Legacy encrypted data requires migration before decrypt');
|
|
329
|
+
}
|
|
330
|
+
const vaultKey = resolveVaultKey(secret);
|
|
331
|
+
if (!vaultKey) {
|
|
332
|
+
throw new Error('A derived vault secret is required to decrypt v2 key data');
|
|
333
|
+
}
|
|
334
|
+
const key = deriveRecordKey(vaultKey, salt);
|
|
335
|
+
const decipher = createDecipheriv('aes-256-gcm', key, iv);
|
|
336
|
+
decipher.setAuthTag(authTag);
|
|
337
|
+
let decrypted = decipher.update(encryptedText, 'hex', 'utf8');
|
|
338
|
+
decrypted += decipher.final('utf8');
|
|
339
|
+
return decrypted;
|
|
340
|
+
}
|
|
341
|
+
const base58check = require('./utils/base58check');
|
|
342
|
+
/**
|
|
343
|
+
* Validate a private key format.
|
|
344
|
+
* Supports WIF (Base58Check), PVT_K1_* style, and 64-char hex.
|
|
345
|
+
* @param {string} key - Private key to validate
|
|
346
|
+
* @returns {Object} { valid: boolean, reason?: string }
|
|
347
|
+
*/
|
|
348
|
+
function validatePrivateKey(key) {
|
|
349
|
+
if (!key || typeof key !== 'string')
|
|
350
|
+
return { valid: false, reason: 'Empty key' };
|
|
351
|
+
const k = key.trim();
|
|
352
|
+
// Basic characters allowed for base58-like / ASCII keys
|
|
353
|
+
const base58chars = /^[1-9A-HJ-NP-Za-km-z]+$/;
|
|
354
|
+
// Strict WIF validation using base58check decode (verifies checksum & structure)
|
|
355
|
+
try {
|
|
356
|
+
// Base58Check decode throws if checksum or characters are invalid.
|
|
357
|
+
const payload = base58check.decode(k);
|
|
358
|
+
// WIFs for Bitcoin-style keys use 0x80 version byte and payload lengths 33 or 34
|
|
359
|
+
// Uncompressed WIF payload: [0x80 | 32-byte privkey]
|
|
360
|
+
// Compressed WIF payload: [0x80 | 32-byte privkey | 0x01]
|
|
361
|
+
if (payload && payload.length >= 33) {
|
|
362
|
+
// version is first byte
|
|
363
|
+
const version = payload[0];
|
|
364
|
+
if (version === 0x80) {
|
|
365
|
+
// valid WIF format
|
|
366
|
+
// payload length 33 (no compression byte) => uncompressed, 34 => compressed
|
|
367
|
+
if (payload.length === 33 || payload.length === 34) {
|
|
368
|
+
return { valid: true };
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
catch (err) {
|
|
374
|
+
// Not a valid base58check WIF; continue to other formats
|
|
375
|
+
}
|
|
376
|
+
// PVT-style private key used by some Graphene-based chains (e.g. PVT_K1_<data>)
|
|
377
|
+
// Strip prefix and base58check-decode to verify checksum and payload length.
|
|
378
|
+
// This catches typos before the key is encrypted to disk.
|
|
379
|
+
if (/^PVT_(?:K1_)?[A-Za-z0-9_-]+$/.test(k)) {
|
|
380
|
+
try {
|
|
381
|
+
const stripped = k.replace(/^PVT_(?:K1_)?/, '');
|
|
382
|
+
const payload = base58check.decode(stripped);
|
|
383
|
+
if (payload && payload.length === 32) {
|
|
384
|
+
return { valid: true };
|
|
385
|
+
}
|
|
386
|
+
// Graphene PVT_K1_ keys are 32 bytes of key material
|
|
387
|
+
return { valid: false, reason: `PVT_K1_ key decoded to ${payload.length} bytes, expected 32` };
|
|
388
|
+
}
|
|
389
|
+
catch (err) {
|
|
390
|
+
return { valid: false, reason: `PVT_K1_ key has invalid base58check encoding: ${err.message}` };
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
// Hex private key (64 hex chars) - accept optionally
|
|
394
|
+
if (/^[0-9a-fA-F]{64}$/.test(k)) {
|
|
395
|
+
return { valid: true };
|
|
396
|
+
}
|
|
397
|
+
return { valid: false, reason: 'Unrecognized key format' };
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Load stored accounts from profiles/keys.json.
|
|
401
|
+
* Returns empty structure if file doesn't exist or is corrupted.
|
|
402
|
+
* @returns {Object} { vaultVersion: number, vaultSalt: string, vaultVerifier: string, masterPasswordHash: string, accounts: Object }
|
|
403
|
+
*/
|
|
404
|
+
function loadAccounts() {
|
|
405
|
+
try {
|
|
406
|
+
return normalizeAccountsData(storage.readJSON(PROFILES_KEYS_FILE));
|
|
407
|
+
}
|
|
408
|
+
catch (error) {
|
|
409
|
+
if (error.code !== 'ENOENT' && !(error instanceof SyntaxError)) {
|
|
410
|
+
console.error('Error loading accounts file, resetting to default:', error.message);
|
|
411
|
+
}
|
|
412
|
+
return normalizeAccountsData();
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
function setupModernVault(accountsData, password) {
|
|
416
|
+
const vaultSalt = randomBytes(VAULT_SALT_BYTES);
|
|
417
|
+
const vaultKey = deriveVaultKey(password, vaultSalt);
|
|
418
|
+
accountsData.vaultVersion = VAULT_VERSION;
|
|
419
|
+
accountsData.vaultSalt = vaultSalt.toString('hex');
|
|
420
|
+
accountsData.vaultVerifier = createVaultVerifier(vaultKey);
|
|
421
|
+
delete accountsData.masterPasswordHash;
|
|
422
|
+
return createVaultSecret(vaultKey);
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Check that the keys file has restrictive permissions (0o600) and is owned by
|
|
426
|
+
* the current user. Returns silently if the file doesn't exist yet (it will be
|
|
427
|
+
* created correctly by saveAccounts).
|
|
428
|
+
*
|
|
429
|
+
* MIGRATION: If the file has the legacy 0o644 mode (from before the atomic-write
|
|
430
|
+
* fix), auto-remediate to 0o600 and log a warning. This prevents the first run
|
|
431
|
+
* after upgrade from crashing with "Unexpected permissions".
|
|
432
|
+
*
|
|
433
|
+
* Should be called early in every entry point that may read or write keys.json.
|
|
434
|
+
*/
|
|
435
|
+
function checkKeysFileSecurity() {
|
|
436
|
+
if (!storage.exists(PROFILES_KEYS_FILE))
|
|
437
|
+
return;
|
|
438
|
+
try {
|
|
439
|
+
assertPrivatePathSecurity(PROFILES_KEYS_FILE, { expectedType: 'file', requiredMode: 0o600 });
|
|
440
|
+
}
|
|
441
|
+
catch (err) {
|
|
442
|
+
// Auto-remediate legacy 0o644 mode (the state per the security audit)
|
|
443
|
+
const stat = storage.lstat(PROFILES_KEYS_FILE);
|
|
444
|
+
const mode = stat.mode & 0o777;
|
|
445
|
+
if (mode === 0o644 && !stat.isSymbolicLink()) {
|
|
446
|
+
storage.chmod(PROFILES_KEYS_FILE, 0o600);
|
|
447
|
+
chainKeysLogger.warn(`[security] Auto-fixed ${PROFILES_KEYS_FILE} permissions from 0o644 to 0o600. Run: chmod 600 profiles/keys.json`);
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
// For any other security issue (symlink, wrong owner, unexpected mode),
|
|
451
|
+
// fail closed — this is a real security violation, not a migration artifact.
|
|
452
|
+
throw err;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Unlock the key vault with a master password.
|
|
457
|
+
* Uses modern scrypt v2 vault format with HMAC verification.
|
|
458
|
+
* @param {string} password - Master password
|
|
459
|
+
* @param {import('./types').KeysFile} [accountsData=loadAccounts()] - Accounts data object
|
|
460
|
+
* @returns {import('./types').VaultSecret} Derived vault secret
|
|
461
|
+
* @throws {MasterPasswordError} If password is incorrect
|
|
462
|
+
* @throws {Error} If vault format is unsupported
|
|
463
|
+
*/
|
|
464
|
+
function unlockWithPassword(password, accountsData = loadAccounts()) {
|
|
465
|
+
if (!hasModernVault(accountsData)) {
|
|
466
|
+
if (Object.keys(accountsData.accounts || {}).length > 0) {
|
|
467
|
+
throw new Error('Unsupported key vault format. Recreate profiles/keys.json with the current key manager.');
|
|
468
|
+
}
|
|
469
|
+
throw new Error('No master password set. Please run modules/chain_keys.ts first.');
|
|
470
|
+
}
|
|
471
|
+
if (!verifyModernPassword(password, accountsData)) {
|
|
472
|
+
throw new MasterPasswordError('Incorrect master password.');
|
|
473
|
+
}
|
|
474
|
+
return deriveModernSecretFromPassword(password, accountsData);
|
|
475
|
+
}
|
|
476
|
+
function verifyCurrentPassword(password, accountsData) {
|
|
477
|
+
return hasModernVault(accountsData) && verifyModernPassword(password, accountsData);
|
|
478
|
+
}
|
|
479
|
+
class MasterPasswordError extends Error {
|
|
480
|
+
static code = 'MASTER_PASSWORD_FAILED';
|
|
481
|
+
code;
|
|
482
|
+
constructor(message) {
|
|
483
|
+
super(message);
|
|
484
|
+
this.name = 'MasterPasswordError';
|
|
485
|
+
this.code = MasterPasswordError.code;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Check if an error is a master password authentication failure.
|
|
490
|
+
* @param {Error} err - Error to check
|
|
491
|
+
* @returns {boolean} True if the error indicates a master password failure
|
|
492
|
+
*/
|
|
493
|
+
function isMasterPasswordFailure(err) {
|
|
494
|
+
return !!(err && (err instanceof MasterPasswordError || err.code === MasterPasswordError.code));
|
|
495
|
+
}
|
|
496
|
+
const MASTER_PASSWORD_MAX_ATTEMPTS = CREDENTIAL_PROMPTS.MAX_MASTER_PASSWORD_ATTEMPTS;
|
|
497
|
+
let masterPasswordAttempts = 0;
|
|
498
|
+
/**
|
|
499
|
+
* Prompts the user for the master password with retry tracking.
|
|
500
|
+
* @returns {Promise<string>} The entered password.
|
|
501
|
+
* @throws {MasterPasswordError} If max attempts are reached.
|
|
502
|
+
* @private
|
|
503
|
+
*/
|
|
504
|
+
async function _promptPassword() {
|
|
505
|
+
if (masterPasswordAttempts >= MASTER_PASSWORD_MAX_ATTEMPTS) {
|
|
506
|
+
throw new MasterPasswordError(`Incorrect master password after ${MASTER_PASSWORD_MAX_ATTEMPTS} attempts.`);
|
|
507
|
+
}
|
|
508
|
+
masterPasswordAttempts += 1;
|
|
509
|
+
// Use readPassword instead of readlineSync to support Delete key and consistent masking
|
|
510
|
+
return await readPassword('Enter master password: ');
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* Authenticate and return a derived vault secret.
|
|
514
|
+
* Prompts user interactively with limited retry attempts.
|
|
515
|
+
* @returns {Promise<Object>} The verified vault secret
|
|
516
|
+
* @throws {Error} If no master password is set
|
|
517
|
+
* @throws {MasterPasswordError} If max attempts exceeded
|
|
518
|
+
*/
|
|
519
|
+
async function authenticate() {
|
|
520
|
+
const accountsData = loadAccounts();
|
|
521
|
+
try {
|
|
522
|
+
while (true) {
|
|
523
|
+
// Enforce the attempt limit at the top of the loop as well as inside
|
|
524
|
+
// _promptPassword. _promptPassword also checks the limit so that
|
|
525
|
+
// any other future caller (or a refactor that removes the check
|
|
526
|
+
// here) cannot accidentally produce an infinite prompt loop. This
|
|
527
|
+
// explicit check is the authoritative exit path.
|
|
528
|
+
if (masterPasswordAttempts >= MASTER_PASSWORD_MAX_ATTEMPTS) {
|
|
529
|
+
throw new MasterPasswordError(`Incorrect master password after ${MASTER_PASSWORD_MAX_ATTEMPTS} attempts.`);
|
|
530
|
+
}
|
|
531
|
+
const enteredPassword = await _promptPassword();
|
|
532
|
+
try {
|
|
533
|
+
const secret = unlockWithPassword(enteredPassword, accountsData);
|
|
534
|
+
masterPasswordAttempts = 0;
|
|
535
|
+
return secret;
|
|
536
|
+
}
|
|
537
|
+
catch (error) {
|
|
538
|
+
if (!(error instanceof MasterPasswordError)) {
|
|
539
|
+
throw error;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
console.log('Master password not correct. Please try again.');
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
catch (err) {
|
|
546
|
+
if (err instanceof MasterPasswordError) {
|
|
547
|
+
masterPasswordAttempts = 0;
|
|
548
|
+
}
|
|
549
|
+
throw err;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Retrieve and decrypt a stored private key.
|
|
554
|
+
* @param {string} accountName - Name of the account
|
|
555
|
+
* @param {Object|Buffer} vaultSecret - Derived vault secret
|
|
556
|
+
* @returns {string} Decrypted private key
|
|
557
|
+
* @throws {Error} If account not found
|
|
558
|
+
*/
|
|
559
|
+
function getPrivateKey(accountName, vaultSecret) {
|
|
560
|
+
const accountsData = loadAccounts();
|
|
561
|
+
const account = accountsData.accounts[accountName];
|
|
562
|
+
if (!account) {
|
|
563
|
+
throw new Error(`Account '${accountName}' not found.`);
|
|
564
|
+
}
|
|
565
|
+
if (!isVersionedEncryptedPayload(account.encryptedKey)) {
|
|
566
|
+
throw new Error('Legacy encrypted data should have been migrated during unlock');
|
|
567
|
+
}
|
|
568
|
+
return decrypt(account.encryptedKey, vaultSecret);
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Resolve a signing key for an account, following on-chain authority structures
|
|
572
|
+
* (account_auths, key_auths) when no direct key is stored.
|
|
573
|
+
*
|
|
574
|
+
* @param {string} accountName - Target account to sign for
|
|
575
|
+
* @param {Object|Buffer} vaultSecret - Derived vault secret
|
|
576
|
+
* @param {object} chainClient - Native chain client with db.get_full_accounts
|
|
577
|
+
* @returns {Promise<string>} Private key WIF string
|
|
578
|
+
* @throws {Error} If no key can be found through direct lookup or authority resolution
|
|
579
|
+
*/
|
|
580
|
+
async function resolvePrivateKey(accountName, vaultSecret, chainClient) {
|
|
581
|
+
const pubKeyCache = new Map();
|
|
582
|
+
const tryGetKey = async (name) => {
|
|
583
|
+
try {
|
|
584
|
+
return getPrivateKey(name, vaultSecret);
|
|
585
|
+
}
|
|
586
|
+
catch (e) {
|
|
587
|
+
return null;
|
|
588
|
+
}
|
|
589
|
+
};
|
|
590
|
+
const listNames = () => {
|
|
591
|
+
try {
|
|
592
|
+
const data = loadAccounts();
|
|
593
|
+
return data && data.accounts ? Object.keys(data.accounts) : [];
|
|
594
|
+
}
|
|
595
|
+
catch (e) {
|
|
596
|
+
return [];
|
|
597
|
+
}
|
|
598
|
+
};
|
|
599
|
+
return resolveAuthKey(accountName, chainClient, tryGetKey, listNames, 0, pubKeyCache);
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* Display stored account names to console.
|
|
603
|
+
* @param {Object} accounts - Accounts object from loadAccounts()
|
|
604
|
+
* @returns {Array<string>} Array of account names
|
|
605
|
+
*/
|
|
606
|
+
function listKeyNames(accounts) {
|
|
607
|
+
if (!accounts || Object.keys(accounts).length === 0) {
|
|
608
|
+
console.log(' (no accounts stored yet)');
|
|
609
|
+
return [];
|
|
610
|
+
}
|
|
611
|
+
console.log('Stored keys:');
|
|
612
|
+
return Object.keys(accounts).map((name, index) => {
|
|
613
|
+
console.log(` ${index + 1}. ${name}`);
|
|
614
|
+
return name;
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Prompts the user to select an account name from the stored keys.
|
|
619
|
+
* @param {Object} accounts - The accounts object.
|
|
620
|
+
* @param {string} promptText - The prompt message to display.
|
|
621
|
+
* @returns {Promise<string|null>} The selected account name, or null/ESC.
|
|
622
|
+
*/
|
|
623
|
+
async function selectKeyName(accounts, promptText) {
|
|
624
|
+
const names = Object.keys(accounts);
|
|
625
|
+
if (!names.length) {
|
|
626
|
+
console.log('No accounts available to select.');
|
|
627
|
+
return null;
|
|
628
|
+
}
|
|
629
|
+
names.forEach((name, index) => console.log(` ${index + 1}. ${name}`));
|
|
630
|
+
const raw = (await readInput(`${promptText} [1-${names.length}]: `)).trim();
|
|
631
|
+
if (raw === '\x1b')
|
|
632
|
+
return '\x1b';
|
|
633
|
+
const idx = Number(raw) - 1;
|
|
634
|
+
if (Number.isNaN(idx) || idx < 0 || idx >= names.length) {
|
|
635
|
+
if (raw !== '')
|
|
636
|
+
console.log('Invalid selection.');
|
|
637
|
+
return null;
|
|
638
|
+
}
|
|
639
|
+
return names[idx];
|
|
640
|
+
}
|
|
641
|
+
/**
|
|
642
|
+
* Interactively changes the master password and re-encrypts all stored keys.
|
|
643
|
+
* @param {Object} accountsData - The loaded accounts data object.
|
|
644
|
+
* @param {Object|Buffer|null} currentSecret - The current derived secret.
|
|
645
|
+
* @returns {Promise<Object|Buffer|null>} The new vault secret, or the old one if failed/cancelled.
|
|
646
|
+
*/
|
|
647
|
+
async function changeMasterPassword(accountsData, currentSecret) {
|
|
648
|
+
if (!hasModernVault(accountsData) && !accountsData.masterPasswordHash) {
|
|
649
|
+
console.log('No master password is set yet.');
|
|
650
|
+
return currentSecret;
|
|
651
|
+
}
|
|
652
|
+
const oldPassword = await readPassword('Enter current master password: ');
|
|
653
|
+
if (oldPassword === '\x1b')
|
|
654
|
+
return currentSecret;
|
|
655
|
+
if (!verifyCurrentPassword(oldPassword, accountsData)) {
|
|
656
|
+
console.log('Incorrect master password!');
|
|
657
|
+
return currentSecret;
|
|
658
|
+
}
|
|
659
|
+
const oldSecret = deriveModernSecretFromPassword(oldPassword, accountsData);
|
|
660
|
+
const newPassword = await readPassword('Enter new master password: ');
|
|
661
|
+
if (newPassword === '\x1b')
|
|
662
|
+
return currentSecret;
|
|
663
|
+
const confirmPassword = await readPassword('Confirm new master password: ');
|
|
664
|
+
if (confirmPassword === '\x1b')
|
|
665
|
+
return currentSecret;
|
|
666
|
+
if (newPassword !== confirmPassword) {
|
|
667
|
+
console.log('Passwords do not match!');
|
|
668
|
+
return currentSecret;
|
|
669
|
+
}
|
|
670
|
+
if (!newPassword) {
|
|
671
|
+
console.log('New master password cannot be empty.');
|
|
672
|
+
return currentSecret;
|
|
673
|
+
}
|
|
674
|
+
const decryptedKeys = {};
|
|
675
|
+
try {
|
|
676
|
+
for (const [name, account] of Object.entries(accountsData.accounts)) {
|
|
677
|
+
decryptedKeys[name] = decrypt(account.encryptedKey, oldSecret);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
catch (error) {
|
|
681
|
+
// Clear any partially-decrypted keys before returning
|
|
682
|
+
for (const key of Object.keys(decryptedKeys))
|
|
683
|
+
delete decryptedKeys[key];
|
|
684
|
+
console.log('Failed to decrypt stored keys with the current master password:', error.message);
|
|
685
|
+
return currentSecret;
|
|
686
|
+
}
|
|
687
|
+
const newSecret = setupModernVault(accountsData, newPassword);
|
|
688
|
+
for (const [name, account] of Object.entries(accountsData.accounts)) {
|
|
689
|
+
account.encryptedKey = encrypt(decryptedKeys[name], newSecret);
|
|
690
|
+
delete decryptedKeys[name];
|
|
691
|
+
}
|
|
692
|
+
// V8 strings are immutable and cannot be zeroed; deleting the references
|
|
693
|
+
// allows GC to collect them. The real protection is that the window
|
|
694
|
+
// between decrypt and re-encrypt is now minimized to the loop body.
|
|
695
|
+
saveAccounts(accountsData);
|
|
696
|
+
console.log('Master password updated successfully.');
|
|
697
|
+
return newSecret;
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* Save accounts data to profiles/keys.json atomically with restrictive permissions.
|
|
701
|
+
* Writes to a temp file in the same directory, fsyncs, then renames over the target.
|
|
702
|
+
* The file is always created with mode 0o600 so that even if the calling process
|
|
703
|
+
* inherited a permissive umask (e.g. 0o022), the key material is never world-readable.
|
|
704
|
+
*
|
|
705
|
+
* @param {Object} data - Accounts data to save
|
|
706
|
+
*/
|
|
707
|
+
function saveAccounts(data) {
|
|
708
|
+
// Always save sensitive data to the live path (ignored by git)
|
|
709
|
+
ensureProfilesKeysDirectory();
|
|
710
|
+
const serialized = {
|
|
711
|
+
vaultVersion: data && Number(data.vaultVersion) ? Number(data.vaultVersion) : 0,
|
|
712
|
+
vaultSalt: data && typeof data.vaultSalt === 'string' ? data.vaultSalt : '',
|
|
713
|
+
vaultVerifier: data && typeof data.vaultVerifier === 'string' ? data.vaultVerifier : '',
|
|
714
|
+
masterPasswordHash: data && typeof data.masterPasswordHash === 'string' ? data.masterPasswordHash : '',
|
|
715
|
+
accounts: data && data.accounts && typeof data.accounts === 'object' ? data.accounts : {},
|
|
716
|
+
};
|
|
717
|
+
if (!serialized.masterPasswordHash) {
|
|
718
|
+
delete serialized.masterPasswordHash;
|
|
719
|
+
}
|
|
720
|
+
if (!serialized.vaultSalt) {
|
|
721
|
+
delete serialized.vaultSalt;
|
|
722
|
+
}
|
|
723
|
+
if (!serialized.vaultVerifier) {
|
|
724
|
+
delete serialized.vaultVerifier;
|
|
725
|
+
}
|
|
726
|
+
if (!hasModernVault(serialized)) {
|
|
727
|
+
delete serialized.vaultVersion;
|
|
728
|
+
}
|
|
729
|
+
// Atomic write via unified StorageAdapter: tmp file with 0o600 + fsync,
|
|
730
|
+
// then rename over target.
|
|
731
|
+
storage.writeJSON(PROFILES_KEYS_FILE, serialized, { mode: 0o600, fsync: true });
|
|
732
|
+
}
|
|
733
|
+
/**
|
|
734
|
+
* Launch the interactive key management CLI.
|
|
735
|
+
* Provides menu for: add/modify/remove keys, test decryption,
|
|
736
|
+
* change master password.
|
|
737
|
+
*/
|
|
738
|
+
async function main() {
|
|
739
|
+
console.log('Chain Key Manager');
|
|
740
|
+
console.log('========================');
|
|
741
|
+
let accountsData = loadAccounts();
|
|
742
|
+
let vaultSecret = null;
|
|
743
|
+
// Check if master password is set
|
|
744
|
+
if (!hasModernVault(accountsData)) {
|
|
745
|
+
console.log('No master password set. Please set one:');
|
|
746
|
+
const password1 = await readPassword('Enter master password: ');
|
|
747
|
+
const password2 = await readPassword('Confirm master password: ');
|
|
748
|
+
if (password1 !== password2) {
|
|
749
|
+
console.log('Passwords do not match!');
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
vaultSecret = setupModernVault(accountsData, password1);
|
|
753
|
+
saveAccounts(accountsData);
|
|
754
|
+
console.log('Master password set successfully.');
|
|
755
|
+
}
|
|
756
|
+
else {
|
|
757
|
+
try {
|
|
758
|
+
vaultSecret = await authenticate();
|
|
759
|
+
accountsData = loadAccounts();
|
|
760
|
+
console.log('Authenticated successfully.');
|
|
761
|
+
}
|
|
762
|
+
catch (err) {
|
|
763
|
+
if (err instanceof MasterPasswordError) {
|
|
764
|
+
console.log(err.message);
|
|
765
|
+
return;
|
|
766
|
+
}
|
|
767
|
+
throw err;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
while (true) {
|
|
771
|
+
console.log('\nMenu:');
|
|
772
|
+
console.log('1. Add key');
|
|
773
|
+
console.log('2. Modify key');
|
|
774
|
+
console.log('3. Remove key');
|
|
775
|
+
console.log('4. List keys');
|
|
776
|
+
console.log('5. Test decryption');
|
|
777
|
+
console.log('6. Change master password');
|
|
778
|
+
console.log('7. Exit (or press Enter)');
|
|
779
|
+
const choiceRaw = await readInput('Choose an option: ');
|
|
780
|
+
console.log('');
|
|
781
|
+
if (choiceRaw === '\x1b' || choiceRaw.trim() === '') {
|
|
782
|
+
console.log('Keymanager closed!');
|
|
783
|
+
break;
|
|
784
|
+
}
|
|
785
|
+
const choice = choiceRaw.trim();
|
|
786
|
+
if (choice === '1') {
|
|
787
|
+
const accountNameRaw = await readInput('Enter account name: ');
|
|
788
|
+
if (accountNameRaw === '\x1b')
|
|
789
|
+
continue;
|
|
790
|
+
const accountName = accountNameRaw.trim();
|
|
791
|
+
if (!accountName) {
|
|
792
|
+
continue;
|
|
793
|
+
}
|
|
794
|
+
const privateKeyRaw = await readPassword('Enter private key: ');
|
|
795
|
+
if (privateKeyRaw === '\x1b')
|
|
796
|
+
continue;
|
|
797
|
+
const privateKey = privateKeyRaw.replace(/\s+/g, '');
|
|
798
|
+
const validation = validatePrivateKey(privateKey);
|
|
799
|
+
if (!validation.valid) {
|
|
800
|
+
console.log(`Invalid private key: ${validation.reason}`);
|
|
801
|
+
console.log('Accepted formats: WIF (51/52 chars), PVT_* keys, or 64-hex');
|
|
802
|
+
continue;
|
|
803
|
+
}
|
|
804
|
+
const encryptedKey = encrypt(privateKey, vaultSecret);
|
|
805
|
+
accountsData.accounts[accountName] = { encryptedKey };
|
|
806
|
+
saveAccounts(accountsData);
|
|
807
|
+
console.log(`Account '${accountName}' added successfully.`);
|
|
808
|
+
}
|
|
809
|
+
else if (choice === '2') {
|
|
810
|
+
const accountName = await selectKeyName(accountsData.accounts, 'Select key to modify');
|
|
811
|
+
if (accountName === '\x1b' || !accountName)
|
|
812
|
+
continue;
|
|
813
|
+
const privateKeyRaw = await readPassword('Enter private key: ');
|
|
814
|
+
if (privateKeyRaw === '\x1b')
|
|
815
|
+
continue;
|
|
816
|
+
const privateKey = privateKeyRaw.replace(/\s+/g, '');
|
|
817
|
+
const validation = validatePrivateKey(privateKey);
|
|
818
|
+
if (!validation.valid) {
|
|
819
|
+
console.log(`Invalid private key: ${validation.reason}`);
|
|
820
|
+
console.log('Accepted formats: WIF (51/52 chars), PVT_* keys, or 64-hex');
|
|
821
|
+
continue;
|
|
822
|
+
}
|
|
823
|
+
const encryptedKey = encrypt(privateKey, vaultSecret);
|
|
824
|
+
accountsData.accounts[accountName] = { ...accountsData.accounts[accountName], encryptedKey };
|
|
825
|
+
saveAccounts(accountsData);
|
|
826
|
+
console.log(`Account '${accountName}' updated successfully.`);
|
|
827
|
+
}
|
|
828
|
+
else if (choice === '3') {
|
|
829
|
+
const accountName = await selectKeyName(accountsData.accounts, 'Select key to remove');
|
|
830
|
+
if (accountName === '\x1b' || !accountName)
|
|
831
|
+
continue;
|
|
832
|
+
const confirm = (await readInput(`Remove '${accountName}'? (y/n): `)).trim().toLowerCase();
|
|
833
|
+
if (confirm === '\x1b')
|
|
834
|
+
continue;
|
|
835
|
+
if (confirm === 'y') {
|
|
836
|
+
delete accountsData.accounts[accountName];
|
|
837
|
+
saveAccounts(accountsData);
|
|
838
|
+
console.log(`Account '${accountName}' removed successfully.`);
|
|
839
|
+
}
|
|
840
|
+
else {
|
|
841
|
+
console.log('Cancelled.');
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
else if (choice === '4') {
|
|
845
|
+
listKeyNames(accountsData.accounts);
|
|
846
|
+
}
|
|
847
|
+
else if (choice === '5') {
|
|
848
|
+
const accountName = await selectKeyName(accountsData.accounts, 'Select key to test');
|
|
849
|
+
if (accountName === '\x1b' || !accountName)
|
|
850
|
+
continue;
|
|
851
|
+
try {
|
|
852
|
+
const decryptedKey = decrypt(accountsData.accounts[accountName].encryptedKey, vaultSecret);
|
|
853
|
+
console.log(`First 5 characters: ${decryptedKey.substring(0, 5)}`);
|
|
854
|
+
}
|
|
855
|
+
catch (error) {
|
|
856
|
+
console.log('Decryption failed - wrong master password or corrupted data');
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
else if (choice === '6') {
|
|
860
|
+
vaultSecret = await changeMasterPassword(accountsData, vaultSecret);
|
|
861
|
+
}
|
|
862
|
+
else if (choice === '7') {
|
|
863
|
+
console.log('Keymanager closed!');
|
|
864
|
+
break;
|
|
865
|
+
}
|
|
866
|
+
else {
|
|
867
|
+
console.log('Invalid choice.');
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
/**
|
|
872
|
+
* Check if dexbot-cred daemon is ready and responsive
|
|
873
|
+
* @param {Object} [options={}] - Optional socket/ready-file path overrides
|
|
874
|
+
* @returns {boolean} True if daemon socket is responsive
|
|
875
|
+
*/
|
|
876
|
+
function isDaemonReady(options = {}) {
|
|
877
|
+
try {
|
|
878
|
+
return storage.exists(getCredentialReadyFilePath(options)) && storage.exists(getCredentialSocketPath(options));
|
|
879
|
+
}
|
|
880
|
+
catch {
|
|
881
|
+
return false;
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* Check if dexbot-cred daemon is actually responsive by opening a socket
|
|
886
|
+
* connection and waiting for any reply. This catches stale socket/ready
|
|
887
|
+
* files left behind by a crashed daemon.
|
|
888
|
+
* @param {Object} options - Optional socket/ready-file path overrides
|
|
889
|
+
* @param {number} timeout - Probe timeout in milliseconds (default 2000)
|
|
890
|
+
* @returns {Promise<boolean>} True if the daemon accepts connections and replies
|
|
891
|
+
*/
|
|
892
|
+
function isDaemonResponsive(options = {}, timeout = 2000) {
|
|
893
|
+
return new Promise((resolve) => {
|
|
894
|
+
if (!isDaemonReady(options)) {
|
|
895
|
+
return resolve(false);
|
|
896
|
+
}
|
|
897
|
+
let net;
|
|
898
|
+
try {
|
|
899
|
+
net = getNet();
|
|
900
|
+
}
|
|
901
|
+
catch {
|
|
902
|
+
return resolve(false);
|
|
903
|
+
}
|
|
904
|
+
const socketPath = getCredentialSocketPath(options);
|
|
905
|
+
const socket = net.createConnection(socketPath);
|
|
906
|
+
let settled = false;
|
|
907
|
+
let responseBuffer = '';
|
|
908
|
+
const timer = setTimeout(() => {
|
|
909
|
+
if (!settled) {
|
|
910
|
+
settled = true;
|
|
911
|
+
socket.destroy();
|
|
912
|
+
resolve(false);
|
|
913
|
+
}
|
|
914
|
+
}, timeout);
|
|
915
|
+
socket.on('connect', () => {
|
|
916
|
+
// Send a minimal request that forces the daemon to reply.
|
|
917
|
+
// Missing fields trigger an error response, which is enough
|
|
918
|
+
// to prove the daemon is alive and processing.
|
|
919
|
+
socket.write('{}\n');
|
|
920
|
+
});
|
|
921
|
+
socket.on('data', (data) => {
|
|
922
|
+
responseBuffer += data.toString();
|
|
923
|
+
if (!settled && responseBuffer.trim().length > 0) {
|
|
924
|
+
settled = true;
|
|
925
|
+
clearTimeout(timer);
|
|
926
|
+
socket.end();
|
|
927
|
+
resolve(true);
|
|
928
|
+
}
|
|
929
|
+
});
|
|
930
|
+
socket.on('error', () => {
|
|
931
|
+
if (!settled) {
|
|
932
|
+
settled = true;
|
|
933
|
+
clearTimeout(timer);
|
|
934
|
+
resolve(false);
|
|
935
|
+
}
|
|
936
|
+
});
|
|
937
|
+
socket.on('end', () => {
|
|
938
|
+
if (!settled) {
|
|
939
|
+
settled = true;
|
|
940
|
+
clearTimeout(timer);
|
|
941
|
+
resolve(false);
|
|
942
|
+
}
|
|
943
|
+
});
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
/**
|
|
947
|
+
* Wait for dexbot-cred daemon to be ready
|
|
948
|
+
* @param {number} maxWaitMs - Maximum time to wait in milliseconds (default 60000)
|
|
949
|
+
* @param {Object} [options] - Optional socket/ready-file path overrides
|
|
950
|
+
* @returns {Promise<void>} Resolves when daemon is ready
|
|
951
|
+
* @throws {Error} If daemon doesn't start within timeout
|
|
952
|
+
*/
|
|
953
|
+
async function waitForDaemon(maxWaitMs = TIMING.DAEMON_STARTUP_TIMEOUT_MS, options = {}) {
|
|
954
|
+
const startTime = Date.now();
|
|
955
|
+
const checkInterval = TIMING.CHECK_INTERVAL_MS; // Check every 100ms
|
|
956
|
+
while (Date.now() - startTime < maxWaitMs) {
|
|
957
|
+
if (isDaemonReady(options)) {
|
|
958
|
+
return;
|
|
959
|
+
}
|
|
960
|
+
await sleep(checkInterval);
|
|
961
|
+
}
|
|
962
|
+
throw new Error(`Daemon did not start within ${maxWaitMs}ms`);
|
|
963
|
+
}
|
|
964
|
+
/**
|
|
965
|
+
* Send a single-line JSON request to the credential daemon and return
|
|
966
|
+
* the parsed response via extractResult.
|
|
967
|
+
* @param {string} requestType - The "type" field sent to the daemon
|
|
968
|
+
* @param {string} accountName - Account name included in the request
|
|
969
|
+
* @param {number} timeout - Timeout in milliseconds (default 5000)
|
|
970
|
+
* @param {Object} options - Optional socket path overrides
|
|
971
|
+
* @param {string} label - Human label for error messages (e.g. 'request', 'ping', 'probe')
|
|
972
|
+
* @param {function} extractResult - Callback: (response) => resolved value; throw to reject
|
|
973
|
+
* @returns {Promise<*>} Resolved value from extractResult
|
|
974
|
+
*/
|
|
975
|
+
function sendDaemonRequest(requestType, accountName, timeout = TIMING.DAEMON_PING_TIMEOUT_MS, options = {}, label = 'request', extractResult = null) {
|
|
976
|
+
const net = getNet();
|
|
977
|
+
const socketPath = getCredentialSocketPath(options);
|
|
978
|
+
return new Promise((resolve, reject) => {
|
|
979
|
+
let settled = false;
|
|
980
|
+
const socket = net.createConnection(socketPath, () => {
|
|
981
|
+
socket.write(JSON.stringify({ type: requestType, accountName }) + '\n');
|
|
982
|
+
});
|
|
983
|
+
let responseBuffer = '';
|
|
984
|
+
const timer = setTimeout(() => {
|
|
985
|
+
socket.destroy();
|
|
986
|
+
if (!settled) {
|
|
987
|
+
settled = true;
|
|
988
|
+
reject(new Error(`Daemon ${label} timeout`));
|
|
989
|
+
}
|
|
990
|
+
}, timeout);
|
|
991
|
+
socket.on('data', (data) => {
|
|
992
|
+
responseBuffer += data.toString();
|
|
993
|
+
const lines = responseBuffer.split('\n');
|
|
994
|
+
responseBuffer = lines.pop();
|
|
995
|
+
for (const line of lines) {
|
|
996
|
+
if (line.trim()) {
|
|
997
|
+
clearTimeout(timer);
|
|
998
|
+
socket.end();
|
|
999
|
+
if (!settled) {
|
|
1000
|
+
settled = true;
|
|
1001
|
+
let parsed;
|
|
1002
|
+
try {
|
|
1003
|
+
parsed = JSON.parse(line);
|
|
1004
|
+
}
|
|
1005
|
+
catch {
|
|
1006
|
+
reject(new Error(`Invalid daemon ${label} response`));
|
|
1007
|
+
return;
|
|
1008
|
+
}
|
|
1009
|
+
if (extractResult) {
|
|
1010
|
+
resolve(extractResult(parsed));
|
|
1011
|
+
}
|
|
1012
|
+
else if (parsed.success) {
|
|
1013
|
+
resolve(parsed);
|
|
1014
|
+
}
|
|
1015
|
+
else {
|
|
1016
|
+
reject(new Error(parsed.error || `Daemon ${label} failed`));
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
return;
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
});
|
|
1023
|
+
socket.on('error', (error) => {
|
|
1024
|
+
clearTimeout(timer);
|
|
1025
|
+
if (!settled) {
|
|
1026
|
+
settled = true;
|
|
1027
|
+
reject(new Error(`Daemon connection failed: ${error.message}`));
|
|
1028
|
+
}
|
|
1029
|
+
});
|
|
1030
|
+
socket.on('end', () => {
|
|
1031
|
+
clearTimeout(timer);
|
|
1032
|
+
if (!settled && !responseBuffer.trim()) {
|
|
1033
|
+
settled = true;
|
|
1034
|
+
reject(new Error('Daemon closed connection unexpectedly'));
|
|
1035
|
+
}
|
|
1036
|
+
});
|
|
1037
|
+
});
|
|
1038
|
+
}
|
|
1039
|
+
/**
|
|
1040
|
+
* Lightweight daemon health check. Does NOT create a session or write
|
|
1041
|
+
* an audit log entry — used by the credential daemon watchdog and
|
|
1042
|
+
* pre-write probes where only liveness matters.
|
|
1043
|
+
* @param {string} accountName - Ignored for ping; included for API consistency
|
|
1044
|
+
* @param {number} timeout - Timeout in milliseconds (default 5000)
|
|
1045
|
+
* @param {Object} options - Optional socket path overrides
|
|
1046
|
+
* @returns {Promise<boolean>} Resolves with true if daemon responds
|
|
1047
|
+
*/
|
|
1048
|
+
function pingDaemon(accountName, timeout = TIMING.DAEMON_PING_TIMEOUT_MS, options = {}) {
|
|
1049
|
+
return sendDaemonRequest('ping', accountName, timeout, options, 'ping', (response) => {
|
|
1050
|
+
if (response.success && response.pong)
|
|
1051
|
+
return true;
|
|
1052
|
+
throw new Error(response.error || 'Daemon ping failed');
|
|
1053
|
+
});
|
|
1054
|
+
}
|
|
1055
|
+
/**
|
|
1056
|
+
* Verifies the account exists in the daemon's session cache.
|
|
1057
|
+
* @param {string} accountName - Name of the account to probe
|
|
1058
|
+
* @param {number} timeout - Timeout in milliseconds (default 5000)
|
|
1059
|
+
* @param {Object} options - Optional socket path overrides
|
|
1060
|
+
* @returns {Promise<string|null>} Resolves with sessionId if account is available, rejects otherwise
|
|
1061
|
+
*/
|
|
1062
|
+
function probeAccountInDaemon(accountName, timeout = TIMING.DAEMON_PING_TIMEOUT_MS, options = {}) {
|
|
1063
|
+
return sendDaemonRequest('probe-account', accountName, timeout, options, 'probe', (response) => {
|
|
1064
|
+
if (response.success)
|
|
1065
|
+
return response.sessionId || null;
|
|
1066
|
+
throw new Error(response.error || 'Daemon probe failed');
|
|
1067
|
+
});
|
|
1068
|
+
}
|
|
1069
|
+
module.exports = {
|
|
1070
|
+
validatePrivateKey,
|
|
1071
|
+
loadAccounts,
|
|
1072
|
+
saveAccounts,
|
|
1073
|
+
checkKeysFileSecurity,
|
|
1074
|
+
encrypt,
|
|
1075
|
+
decrypt,
|
|
1076
|
+
deriveVaultKey,
|
|
1077
|
+
createDaemonSigningToken,
|
|
1078
|
+
createSessionSecret,
|
|
1079
|
+
createVaultSecret,
|
|
1080
|
+
isVaultSecret,
|
|
1081
|
+
isDaemonSigningToken,
|
|
1082
|
+
unlockWithPassword,
|
|
1083
|
+
main,
|
|
1084
|
+
authenticate,
|
|
1085
|
+
getPrivateKey,
|
|
1086
|
+
resolvePrivateKey,
|
|
1087
|
+
isMasterPasswordFailure,
|
|
1088
|
+
MasterPasswordError,
|
|
1089
|
+
isDaemonReady,
|
|
1090
|
+
isDaemonResponsive,
|
|
1091
|
+
waitForDaemon,
|
|
1092
|
+
probeAccountInDaemon,
|
|
1093
|
+
pingDaemon,
|
|
1094
|
+
};
|
|
1095
|
+
//# sourceMappingURL=chain_keys.js.map
|