- Add OpenOrderInfo struct and OpenOrders field to trading context
- Support new AI actions: place_buy_limit, place_sell_limit, cancel_order, cancel_all_orders
- Include existing open orders in AI prompt to avoid duplicate orders
- Add open orders display table in trader dashboard
- Fix Hyperliquid symbol conversion and order status parsing
- Add i18n translations for open orders
All conflicts were in frontend files where main had beginner-mode features
(BeginnerGuideCards, Claw402 balance alerts, mode switcher, actionable error
helpers) that dev intentionally simplified. Kept dev's version in every case.
Removed unused navigate import in SettingsPage after conflict resolution.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add nil checks for session.TargetRef in all four execute*Action handlers
(Trader/Exchange/Model/Strategy) to prevent panic on corrupted sessions;
actions that don't need a target (query/query_list/create) are excluded.
- Fix toast.success indentation in handleToggleTrader so success messages
only fire when the API call actually succeeds.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix Stop() race condition using sync.Once
- Add ensureHistory() to prevent nil panic in planner/dispatcher
- Add bounds check on trader ID slicing
- Log saveExecutionState and clearSetupState errors instead of discarding
- Remove always-true modelID condition in onboard setup
- Add Chinese setup keywords and expand model name aliases
- Strip max_tokens from claw402 requests to avoid thinking-model budget exhaustion
- Hide Agent nav tab (Beta) pending merge to main
- Sync tests with code changes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(payment): add new DeepSeek V4 models to claw402 endpoints and pricing
- Introduced "deepseek-v4-flash" and "deepseek-v4-pro" endpoints in claw402ModelEndpoints.
- Updated modelPrices to include pricing for the new DeepSeek V4 models.
- Added model constants for the new DeepSeek V4 models in the trader component.
* refactor(claw402): update default model to deepseek-v4-flash across components
- Changed the default model for Claw402 from "glm-5" to "deepseek-v4-flash" in multiple files, including the AI model handler and onboarding logic.
- Updated model constants and configurations in the trader component to reflect the new default model.
- Enhanced the model configuration modal to accommodate the new default model setting.
---------
Co-authored-by: Dean <afei.wuhao@gmail.com>
- Introduced "deepseek-v4-flash" and "deepseek-v4-pro" endpoints in claw402ModelEndpoints.
- Updated modelPrices to include pricing for the new DeepSeek V4 models.
- Added model constants for the new DeepSeek V4 models in the trader component.
Co-authored-by: Dean <afei.wuhao@gmail.com>
1. Prevent double-close panic on Stop() by using sync.Once in Scheduler,
Brain, and Sentinel; remove duplicate Stop() call in main.go
2. Add trade quantity (100k) and leverage (125x) sanity caps to prevent
LLM hallucinations or input errors from reaching the exchange
3. Mask secrets in onboarding setup state — only store "****" markers in
SystemConfig instead of plaintext API keys/secrets
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(store): prevent deletion of active strategies and update translations (#1461)
Co-authored-by: Dean <afei.wuhao@gmail.com>
* fix: allow model switching without re-entering wallet key
Users with existing wallets could not switch AI models because the
"Start Trading" button required a valid private key even when one was
already configured. Now the button is enabled when hasExistingWallet
is true, and handleSubmit passes an empty key so the backend preserves
the existing key.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: replace window.location with useNavigate for routing in auth components (#1470)
Co-authored-by: Dean <afei.wuhao@gmail.com>
* feat(trader): implement margin mode handling for order and leverage settings
* refactor(trader): update SetMarginMode to avoid legacy endpoint and improve logging
* feat(api): enhance strategy handling by integrating claw402 wallet key validation
Added validation for the claw402 model's wallet key during strategy test runs. If the selected AI model is claw402, the server now checks for a valid wallet key and returns appropriate error messages if it's missing or if the model fails to load. This ensures better error handling and user feedback when working with AI models.
* refactor(api): streamline claw402 wallet key retrieval and error handling
Refactored the strategy handling logic to encapsulate claw402 wallet key retrieval in a new method, `resolveStrategyDataWalletKey`. This improves code readability and maintains consistent error handling for missing or invalid wallet keys during strategy test runs. The changes enhance the overall robustness of the AI model integration.
* feat(trader): add claw402 wallet key resolution for trader configuration
Implemented a new method, `resolveTraderDataWalletKey`, to retrieve the claw402 wallet key based on the selected AI model and user ID. This enhancement allows for better integration of the claw402 model within the trader configuration, ensuring that the correct wallet key is used for trading operations. The `AutoTraderConfig` struct has been updated to include the new `Claw402WalletKey` field, improving the overall handling of wallet keys in the trading process.
* feat(claw402): preflight USDC balance before AI calls (#1479)
* chore: ignore nofx-server build artifact
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(claw402): preflight USDC balance before AI calls
Short-circuit claw402 Call/CallWithRequestFull when the wallet balance
can't cover the estimated cost of the call, surfacing ErrInsufficientFunds
instead of letting x402 fail mid-flight after the sign step.
- wallet: cached balance lookup (30s TTL, per-address mutex) to avoid
hammering the Base RPC; separate error-returning and display-only APIs
so callers can distinguish zero balance from an unreachable RPC.
- claw402: 1.5× safety multiplier on the flat per-call estimate, 4.0×
for reasoner models whose chain-of-thought cost can blow past the
flat rate. Fail-open on RPC errors — x402 still gates actually-empty
wallets, and we prefer availability over extra strictness.
- shortAddr redacts the wallet in error strings to avoid leaking the
full address into telemetry bundles.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(telemetry): report token usage for SSE streaming paths (#1475)
* fix(telemetry): report token usage for SSE streaming paths
ParseSSEStream already parsed the usage block from SSE chunks but only
printed it, so claw402 streaming calls (and native streaming) never
fired TokenUsageCallback. GA4 therefore undercounted AI usage on the
streaming path.
Return the parsed usage from ParseSSEStream and have both callers fire
the callback with their own Provider/Model.
* chore: drop leftover debug Printf in ParseSSEStream
Telemetry is now wired via TokenUsageCallback, so the Printf is
redundant noise in the stream path.
* fix(gemini): update default model to gemini-3.1-pro
Google discontinued gemini-3-pro-preview on 2026-03-26 and directs all
callers to gemini-3.1-pro / gemini-3.1-pro-preview. Users on their own
API key were getting errors from the native Gemini endpoint because the
provider default pointed at the retired ID. Claw402 was unaffected
because its route map already used gemini-3.1-pro.
Align both the native provider default and the handler's preset list
with gemini-3.1-pro so every code path sends a live model ID.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: extract ResolveClaw402WalletKey to store layer and expand OKX margin mode tests
- Move duplicated claw402 wallet resolution logic into store.AIModelStore.ResolveClaw402WalletKey
- api/strategy.go and manager/trader_manager.go now delegate to the shared method
- Add detailed doc comment on OKX SetMarginMode explaining the local-state-only approach
and why the legacy /api/v5/account/set-isolated-mode endpoint is not called
- Add 3 new test cases: cross mode leverage, OpenShort tdMode, SetTakeProfit tdMode
* fix(auth): prevent SetupPage remount from wiping freshly-set auth token (#1481)
After #1470 moved routing into react-router, SetupPage is rendered at two
different tree positions (top-level guard + /setup Route). When register
success flushSync-sets `user`, the top-level guard stops matching and the
Route-level SetupPage mounts as a new instance, re-running its cleanup
useEffect and removing the auth_token that handlePostAuthSuccess just wrote.
Subsequent requests 401 and bounce the user back to /login.
Redirect /setup to /welcome when user is already set so SetupPage is never
re-mounted during the auth transition.
* fix(wallet): handle JSON-RPC null error field in balance query
Some RPC implementations return explicit "error": null on success.
json.RawMessage deserializes this as the 4-byte literal "null", so
len() > 0 was true, causing every balance query to fail with
"rpc error: null". Skip the null literal to avoid false positives.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(readme): add quick demo video to localized READMEs (#1486)
* docs(README): add quick demo section with video link and image
* docs(README): update demo video link
* docs(i18n): add quick demo section with video link and image for multiple languages
---------
Co-authored-by: Dean <afei.wuhao@gmail.com>
---------
Co-authored-by: deanokk <wuhao@vergex.trade>
Co-authored-by: Dean <afei.wuhao@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: root <root@localhost.localdomain>
* docs(README): add quick demo section with video link and image
* docs(README): update demo video link
* docs(i18n): add quick demo section with video link and image for multiple languages
---------
Co-authored-by: Dean <afei.wuhao@gmail.com>
* feat(store): prevent deletion of active strategies and update translations (#1461)
Co-authored-by: Dean <afei.wuhao@gmail.com>
* fix: allow model switching without re-entering wallet key
Users with existing wallets could not switch AI models because the
"Start Trading" button required a valid private key even when one was
already configured. Now the button is enabled when hasExistingWallet
is true, and handleSubmit passes an empty key so the backend preserves
the existing key.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: replace window.location with useNavigate for routing in auth components (#1470)
Co-authored-by: Dean <afei.wuhao@gmail.com>
* feat(trader): implement margin mode handling for order and leverage settings
* refactor(trader): update SetMarginMode to avoid legacy endpoint and improve logging
* feat(api): enhance strategy handling by integrating claw402 wallet key validation
Added validation for the claw402 model's wallet key during strategy test runs. If the selected AI model is claw402, the server now checks for a valid wallet key and returns appropriate error messages if it's missing or if the model fails to load. This ensures better error handling and user feedback when working with AI models.
* refactor(api): streamline claw402 wallet key retrieval and error handling
Refactored the strategy handling logic to encapsulate claw402 wallet key retrieval in a new method, `resolveStrategyDataWalletKey`. This improves code readability and maintains consistent error handling for missing or invalid wallet keys during strategy test runs. The changes enhance the overall robustness of the AI model integration.
* feat(trader): add claw402 wallet key resolution for trader configuration
Implemented a new method, `resolveTraderDataWalletKey`, to retrieve the claw402 wallet key based on the selected AI model and user ID. This enhancement allows for better integration of the claw402 model within the trader configuration, ensuring that the correct wallet key is used for trading operations. The `AutoTraderConfig` struct has been updated to include the new `Claw402WalletKey` field, improving the overall handling of wallet keys in the trading process.
* feat(claw402): preflight USDC balance before AI calls (#1479)
* chore: ignore nofx-server build artifact
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(claw402): preflight USDC balance before AI calls
Short-circuit claw402 Call/CallWithRequestFull when the wallet balance
can't cover the estimated cost of the call, surfacing ErrInsufficientFunds
instead of letting x402 fail mid-flight after the sign step.
- wallet: cached balance lookup (30s TTL, per-address mutex) to avoid
hammering the Base RPC; separate error-returning and display-only APIs
so callers can distinguish zero balance from an unreachable RPC.
- claw402: 1.5× safety multiplier on the flat per-call estimate, 4.0×
for reasoner models whose chain-of-thought cost can blow past the
flat rate. Fail-open on RPC errors — x402 still gates actually-empty
wallets, and we prefer availability over extra strictness.
- shortAddr redacts the wallet in error strings to avoid leaking the
full address into telemetry bundles.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(telemetry): report token usage for SSE streaming paths (#1475)
* fix(telemetry): report token usage for SSE streaming paths
ParseSSEStream already parsed the usage block from SSE chunks but only
printed it, so claw402 streaming calls (and native streaming) never
fired TokenUsageCallback. GA4 therefore undercounted AI usage on the
streaming path.
Return the parsed usage from ParseSSEStream and have both callers fire
the callback with their own Provider/Model.
* chore: drop leftover debug Printf in ParseSSEStream
Telemetry is now wired via TokenUsageCallback, so the Printf is
redundant noise in the stream path.
* fix(gemini): update default model to gemini-3.1-pro
Google discontinued gemini-3-pro-preview on 2026-03-26 and directs all
callers to gemini-3.1-pro / gemini-3.1-pro-preview. Users on their own
API key were getting errors from the native Gemini endpoint because the
provider default pointed at the retired ID. Claw402 was unaffected
because its route map already used gemini-3.1-pro.
Align both the native provider default and the handler's preset list
with gemini-3.1-pro so every code path sends a live model ID.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: extract ResolveClaw402WalletKey to store layer and expand OKX margin mode tests
- Move duplicated claw402 wallet resolution logic into store.AIModelStore.ResolveClaw402WalletKey
- api/strategy.go and manager/trader_manager.go now delegate to the shared method
- Add detailed doc comment on OKX SetMarginMode explaining the local-state-only approach
and why the legacy /api/v5/account/set-isolated-mode endpoint is not called
- Add 3 new test cases: cross mode leverage, OpenShort tdMode, SetTakeProfit tdMode
* fix(auth): prevent SetupPage remount from wiping freshly-set auth token (#1481)
After #1470 moved routing into react-router, SetupPage is rendered at two
different tree positions (top-level guard + /setup Route). When register
success flushSync-sets `user`, the top-level guard stops matching and the
Route-level SetupPage mounts as a new instance, re-running its cleanup
useEffect and removing the auth_token that handlePostAuthSuccess just wrote.
Subsequent requests 401 and bounce the user back to /login.
Redirect /setup to /welcome when user is already set so SetupPage is never
re-mounted during the auth transition.
* fix(wallet): handle JSON-RPC null error field in balance query
Some RPC implementations return explicit "error": null on success.
json.RawMessage deserializes this as the 4-byte literal "null", so
len() > 0 was true, causing every balance query to fail with
"rpc error: null". Skip the null literal to avoid false positives.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: deanokk <wuhao@vergex.trade>
Co-authored-by: Dean <afei.wuhao@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: root <root@localhost.localdomain>
Some RPC implementations return explicit "error": null on success.
json.RawMessage deserializes this as the 4-byte literal "null", so
len() > 0 was true, causing every balance query to fail with
"rpc error: null". Skip the null literal to avoid false positives.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After #1470 moved routing into react-router, SetupPage is rendered at two
different tree positions (top-level guard + /setup Route). When register
success flushSync-sets `user`, the top-level guard stops matching and the
Route-level SetupPage mounts as a new instance, re-running its cleanup
useEffect and removing the auth_token that handlePostAuthSuccess just wrote.
Subsequent requests 401 and bounce the user back to /login.
Redirect /setup to /welcome when user is already set so SetupPage is never
re-mounted during the auth transition.
Merges PR #1476 from deanokk with the following additions:
- OKX margin mode fix: cross/isolated honored end-to-end via mgnMode/tdMode
- claw402 wallet routing fix: trader path now explicitly resolves user wallet
- refactor: ResolveClaw402WalletKey extracted to store layer (no duplication)
- OKX SetMarginMode documented as local-state-only (no legacy API call)
- OKX margin mode tests expanded: cross mode, OpenShort, SetTakeProfit
- Move duplicated claw402 wallet resolution logic into store.AIModelStore.ResolveClaw402WalletKey
- api/strategy.go and manager/trader_manager.go now delegate to the shared method
- Add detailed doc comment on OKX SetMarginMode explaining the local-state-only approach
and why the legacy /api/v5/account/set-isolated-mode endpoint is not called
- Add 3 new test cases: cross mode leverage, OpenShort tdMode, SetTakeProfit tdMode
Google discontinued gemini-3-pro-preview on 2026-03-26 and directs all
callers to gemini-3.1-pro / gemini-3.1-pro-preview. Users on their own
API key were getting errors from the native Gemini endpoint because the
provider default pointed at the retired ID. Claw402 was unaffected
because its route map already used gemini-3.1-pro.
Align both the native provider default and the handler's preset list
with gemini-3.1-pro so every code path sends a live model ID.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(telemetry): report token usage for SSE streaming paths
ParseSSEStream already parsed the usage block from SSE chunks but only
printed it, so claw402 streaming calls (and native streaming) never
fired TokenUsageCallback. GA4 therefore undercounted AI usage on the
streaming path.
Return the parsed usage from ParseSSEStream and have both callers fire
the callback with their own Provider/Model.
* chore: drop leftover debug Printf in ParseSSEStream
Telemetry is now wired via TokenUsageCallback, so the Printf is
redundant noise in the stream path.
* chore: ignore nofx-server build artifact
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(claw402): preflight USDC balance before AI calls
Short-circuit claw402 Call/CallWithRequestFull when the wallet balance
can't cover the estimated cost of the call, surfacing ErrInsufficientFunds
instead of letting x402 fail mid-flight after the sign step.
- wallet: cached balance lookup (30s TTL, per-address mutex) to avoid
hammering the Base RPC; separate error-returning and display-only APIs
so callers can distinguish zero balance from an unreachable RPC.
- claw402: 1.5× safety multiplier on the flat per-call estimate, 4.0×
for reasoner models whose chain-of-thought cost can blow past the
flat rate. Fail-open on RPC errors — x402 still gates actually-empty
wallets, and we prefer availability over extra strictness.
- shortAddr redacts the wallet in error strings to avoid leaking the
full address into telemetry bundles.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Implemented a new method, `resolveTraderDataWalletKey`, to retrieve the claw402 wallet key based on the selected AI model and user ID. This enhancement allows for better integration of the claw402 model within the trader configuration, ensuring that the correct wallet key is used for trading operations. The `AutoTraderConfig` struct has been updated to include the new `Claw402WalletKey` field, improving the overall handling of wallet keys in the trading process.
Refactored the strategy handling logic to encapsulate claw402 wallet key retrieval in a new method, `resolveStrategyDataWalletKey`. This improves code readability and maintains consistent error handling for missing or invalid wallet keys during strategy test runs. The changes enhance the overall robustness of the AI model integration.
Added validation for the claw402 model's wallet key during strategy test runs. If the selected AI model is claw402, the server now checks for a valid wallet key and returns appropriate error messages if it's missing or if the model fails to load. This ensures better error handling and user feedback when working with AI models.
* feat(store): prevent deletion of active strategies and update translations (#1461)
Co-authored-by: Dean <afei.wuhao@gmail.com>
* fix: allow model switching without re-entering wallet key
Users with existing wallets could not switch AI models because the
"Start Trading" button required a valid private key even when one was
already configured. Now the button is enabled when hasExistingWallet
is true, and handleSubmit passes an empty key so the backend preserves
the existing key.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: deanokk <wuhao@vergex.trade>
Co-authored-by: Dean <afei.wuhao@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Users with existing wallets could not switch AI models because the
"Start Trading" button required a valid private key even when one was
already configured. Now the button is enabled when hasExistingWallet
is true, and handleSubmit passes an empty key so the backend preserves
the existing key.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backend was changed to GLM-5 in 8a0f3f5 but frontend still had
hardcoded DeepSeek fallback and onboarding copy.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add account reset functionality for users who forgot their login credentials.
The reset clears authentication data while preserving wallet private keys and
exchange configs, which are automatically adopted by the new account on
re-registration to prevent fund loss.
- Add POST /api/reset-account endpoint
- Add "Forgot account?" button on login page (zh/en/id)
- Orphan ai_models and exchanges are re-assigned to new user on register
- Onboarding reuses existing claw402 wallet instead of generating new one
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: streamline trader selection logic and URL handling in App component
* refactor: update API request handling across components to use silent mode for improved error management
---------
Co-authored-by: Dean <afei.wuhao@gmail.com>
* feat: implement exchange account state management and UI updates
- Added functionality to invalidate exchange account state cache on exchange config updates, creation, and deletion.
- Introduced new API endpoint to fetch exchange account states.
- Updated frontend components to display exchange account states, including status and balance information.
- Enhanced user experience by refreshing exchange account states after relevant actions.
* feat: enhance trader creation readiness in AITradersPage and BeginnerGuideCards
---------
Co-authored-by: Dean <afei.wuhao@gmail.com>
- invalidateSystemConfig() now dispatches a custom event
- useSystemConfig() listens for the event and re-fetches automatically
- Fixes stale initialized=false after register/logout causing
incorrect redirect to SetupPage
- LoginPage/SetupPage: clear localStorage auth tokens on mount
- AuthContext: clear onboarding state on register, invalidate config on logout
- Extract shared LanguageSwitcher component for consistent UI
- Merge duplicate config import in AuthContext
- auto_trader_risk: skip drawdown check when entryPrice <= 0
- AuthContext: redirect to / on logout
- App.tsx: simplify data page navigation
- BeginnerOnboardingPage: add close button to overlay
- Lower MaxCandidateCoins from 50 to 10 (backend)
- Update CoinSourceEditor: options 1-10, default 3, max static coins 10
- Fix NofxSelect dropdown closing on internal scroll
- Fix NofxSelect position flash on open (useLayoutEffect)
- Pass `lang` from register request body to createDefaultStrategies
- Support zh/en/id locales for strategy names and descriptions
- Wrap strategy creation in a transaction to prevent partial writes
- Frontend sends current UI language in register request body
- Strategy list UI: 2-line clamp, unselected border, larger spacing, smaller font for non-zh