444 Commits

Author SHA1 Message Date
tinkle-community
220cb7428b fix(deps): resolve 3 critical Dependabot advisories
- go: bump github.com/jackc/pgx/v5 v5.6.0 -> v5.9.0 (CVE-2026-33815 /
  CVE-2026-33816, memory-safety in the Postgres driver). govulncheck reports
  0 affecting vulnerabilities after the bump.
- ci: pin aquasecurity/trivy-action to commit SHA ed142fd (v0.36.0) instead of
  the mutable @0.28.0 tag (GHSA-69fq-xp46-6x23, brief upstream supply-chain
  compromise). Dependabot now updates the SHA.
- web: bump vitest ^4.0.16 -> ^4.1.0 (lockfile now 4.1.8) for
  GHSA-5xrq-8626-4rwp (Vitest UI server arbitrary file read/exec; dev-only).
2026-06-05 22:19:27 +08:00
tinkle-community
1aea7abc38 fix(security): remove decrypt oracle, redact secret logs, harden auth, bump Go
Address multiple vulnerabilities found during security review:

- Remove unauthenticated POST /api/crypto/decrypt decryption oracle (route,
  handler, dead frontend helper) + regression test. Transport encryption is
  one-directional; the server never needs to decrypt arbitrary client payloads.
- Redact secrets in config-update logs: handler_ai_model/handler_exchange logged
  %+v of decrypted requests, leaking API keys / secret keys / passphrases /
  private keys. Use named types shared with the log sanitizer so the masking
  can never drift again; extend masking to passphrase + lighter_api_key_private_key.
- crypto: require a valid timestamp in DecryptPayload (a missing ts previously
  skipped replay protection entirely).
- crypto: EncryptedString.Value() now fails closed instead of silently
  persisting plaintext secrets when encryption errors.
- auth: per-IP token-bucket rate limiting on /login and /register against online
  brute-force; raise registration password minimum 6 -> 8; add dummy bcrypt
  compare on unknown-email login to close the user-enumeration timing channel.
- IDOR: getTraderFromQuery no longer falls back to the global in-memory trader
  map; trader access is strictly scoped to the authenticated caller.
- Bump Go 1.25.10 -> 1.25.11 to resolve reachable net/textproto and crypto/x509
  stdlib advisories (govulncheck now reports 0 affecting vulnerabilities).
2026-06-05 22:08:26 +08:00
tinkle-community
577a0918c3 fix(security): move account recovery to local CLI, remove unauthenticated reset endpoints
Unauthenticated POST /api/reset-password and /api/reset-account were a
remotely exploitable auth-bypass on public-facing deployments. The confirm
phrase was embedded in the frontend and echoed back by the API, so it was
friction, not authentication: anyone who knew the account email could reset
the password, log in, and obtain a valid JWT.

Recovery now runs as local CLI commands that operate directly on the database
without starting the HTTP server:

  nofx reset-password --email you@example.com
  nofx reset-account

These require shell/file access to the host, which a remote attacker does not
have, so recovery stays safe even when NOFX is exposed to the public internet.

- cli.go: new reset-password / reset-account subcommands (hidden password
  input on a TTY, --password/stdin for scripting, min 8 chars)
- main.go: dispatch subcommands before the server starts (backward compatible
  with the legacy `nofx <dbpath>` arg)
- api: remove public /reset-password and /reset-account routes, their handlers,
  and the public confirm-phrase constants
- web: replace the self-service reset form with CLI instructions; drop the
  AuthContext resetPassword call and the LoginPage reset-account call (en/zh/id)
- telegram: refresh the bot allowlist comment
2026-06-05 10:49:21 +08:00
tinkle-community
2d32a8f6c9 chore(hyperliquid): refresh shared wallet-connect constants
The Hyperliquid wallet-connect flow signs configuration values that
must match what the server expects and what the order placement layer
sends on-chain. The same constants live in four call sites:

  - trader/hyperliquid/trader.go     (used at order placement)
  - api/handler_hyperliquid_wallet.go (returned by the connect endpoint
                                       and validated on submit)
  - web/src/components/common/HyperliquidWalletConnect.tsx
                                       (signed by the user during connect)
  - trader/hyperliquid/builder_fee_test.go
                                       (pins the trader-side value)

Refresh all four together so the surfaces stay in lockstep.
2026-06-02 12:04:28 +08:00
tinkle-community
3c061aee94 fix(security): tighten strategy-market iframe permissions
Two issues in the prior commit that the embedded vergex.trade explore
iframe did not actually need:

  1. `allow=clipboard-write` granted the iframe silent write access to
     the user's clipboard via the Clipboard API. A compromised or
     compromised-by-injection vergex page could overwrite copied
     content — classic clipboard-hijack pattern (e.g. swap a copied
     wallet address right before the user pastes it into a send form).
     The explore view does not need this capability; drop it. Matches
     the existing DataPage.tsx iframe pattern.

  2. No `sandbox` attribute, so the iframe ran with full implicit
     permissions: arbitrary scripts, form submission, top-level
     navigation, modals, pointer lock, etc. Add an explicit sandbox
     whitelist that grants only what the explore view actually uses:

       allow-scripts allow-same-origin allow-forms
       allow-popups allow-popups-to-escape-sandbox

     Notably withheld:
       - allow-top-navigation: the iframe cannot redirect the NOFX
         shell to an arbitrary URL.
       - allow-modals / allow-pointer-lock / allow-orientation-lock:
         not used by the explore page.
       - allow-storage-access-by-user-activation: keeps third-party
         storage access prompts off the embedded surface.

Verified: explore page renders identically; no sandbox-related
violations in the console (residual errors are vergex's own internal
CSP rejecting analytics + asset fetches, unrelated to our embedding).
2026-06-02 01:56:32 +08:00
tinkle-community
30c6abca74 feat(web): inline-embed vergex.trade/explore in the strategy market
vergex.trade now lists the NOFX origins in the enforced CSP
`frame-ancestors` directive for the /explore path:

  frame-ancestors 'self' https://nofxos.ai https://www.nofxos.ai
                  http://127.0.0.1:3000 http://localhost:3000

so cross-origin embedding from any NOFX deployment works. The
X-Frame-Options header is still SAMEORIGIN, but modern browsers honor
the CSP `frame-ancestors` directive when both are present (per CSP
Level 2), and the embed verifies cleanly under Chromium.

Replaces the prior fallback "open in new tab" CTA card with the same
iframe pattern DataPage.tsx already uses for vergex.trade/trending —
single iframe filling the AppChrome content area, full-screen and
clipboard permissions enabled, strict-origin referrer.
2026-06-02 01:49:22 +08:00
tinkle-community
e4adafa364 feat(web): quick-trade button actually trades - auto-start + honest status
The lightning button on the symbol panel was the single biggest
"agent does nothing" complaint: it created a trader and a strategy via
direct REST calls, then handed the user a hardcoded reply that read
"我没有自动启动实盘交易。请到 Traders 面板确认风控后手动 Start" —
i.e. the chat bot openly admitted it bypassed the agent and refused to
do the work the user had clearly asked for.

- web/src/lib/hyperliquidQuickTrade.ts: after createStrategy +
  createTrader (or finding an existing trader), call POST
  /api/traders/:id/start immediately. Report `started`, `reusedTrader`,
  and an optional `startError` so the chat reply can be honest about
  what happened — created vs reused, running vs failed, and why.

- web/src/pages/AgentChatPage.tsx: replace the canned "please start
  manually" reply with one that reflects reality. Success path shows
  the symbol, strategy, 5-min scan interval, and how to halt it via
  chat. Failure path surfaces the actual start error and tells the
  user the trader exists but is not running.

- web/src/lib/hyperliquidQuickTrade.ts: per-symbol prompt now routes
  on category. Stocks (category="stock") get a long-only, momentum-
  seeking prompt — break of high, volume spike, support reclaim, sector
  catalyst — because shorting individual US equities through the agent
  is rarely what the user wants. Crypto stays bidirectional but
  disciplined. The trader-level custom_prompt is rewritten in the same
  style and explicitly forbids rotating to other symbols.
2026-05-29 22:13:51 +08:00
tinkle-community
1851508353 feat(agent): make the assistant agentic - visible tools, LLM voice, full toolset
The agent felt like an artificial idiot because the LLM almost never spoke
for itself: 14+ Go paths injected fmt.Sprintf canned replies, the frontend
filtered out tool-progress events so users saw three dots for 10-20s, the
main prompt told the LLM "be a trading partner" AND "answer only what's
asked", and the planner sliced the toolset by inferred domain so a "BTC
dropped, how much am I losing?" question couldn't see positions and market
at the same time.

- agent/central_brain.go: shouldTrustDeterministicSkillReply now always
  returns false. Successful mutations (trader/strategy/model/exchange
  create/update/start/stop/delete) flow through reviewTaskCompletion so the
  LLM sees the real outcome JSON and writes the user-facing prose. The
  trade-confirmation regex path (handleTradeConfirmation) was already
  outside this code path and is unaffected.

- agent/agent.go: rewrite the Behavior section of the main system prompt.
  Replace the contradictory "answer only what's asked / don't upsell" with
  "lead with the direct answer, then optionally one relevant follow-up
  only when (a) open risk, (b) missing config, or (c) the next step is
  obvious — e.g. created, want me to start it?". Explicitly authorize
  chaining ("if the user says create and start, do both this turn") and
  ban "please wait / I'll get back to you" language because there is no
  background job to come back from.

- agent/tools.go: plannerToolsForText always returns the full 22-tool set
  (new __all__ domain). The old per-domain trimming hid manage_trader from
  market questions and execute_trade from anything that didn't look like
  an explicit trade — cross-domain reasoning was structurally blocked. The
  compact-vs-full strategy schema switch is preserved so mutation intents
  still see the full config schema.

- web/src/components/agent/{AgentStepPanel,ChatMessages}.tsx: stop
  filtering tool: steps. Map raw tool names to friendly labels with emoji
  ("get_positions" → "📊 检查持仓") in zh/en/id. Users now see what the
  agent is doing in real time instead of silence. central_brain routing
  chatter still gets dropped.

- agent/planner_tools_test.go: tests updated to assert the new
  full-toolset behavior and the compact-vs-full strategy schema switch.
2026-05-29 22:13:05 +08:00
tinkle-community
b9ae99da7e fix(deps): bump web transitive deps via npm audit fix
Resolves 12 local advisories (3 high, 3 moderate, 6 low) with zero
direct-dep version changes — all within existing semver ranges:

- axios 1.13.6 -> 1.16.1 (SSRF via NO_PROXY bypass, prototype pollution
  via validateStatus/parseReviver, CRLF injection in multipart bodies,
  null byte injection in URLSearchParams)
- vite 6.4.1 -> 6.4.2 (high)
- lodash 4.17.23 -> 4.18.1 (high)
- postcss 8.5.6 -> 8.5.15 (moderate)
- plus the rest of the transitive graph

package.json is unchanged. tsc passes, frontend container rebuilds
cleanly, login page renders without console errors. Verified via
docker compose up -d --build nofx-frontend.
2026-05-29 16:18:16 +08:00
tinkle-community
75832f9eb2 feat(web): redesign login page and proxy strategy market to vergex.trade
- LoginPage: two-column desktop layout with brand panel (status pill,
  gradient headline, stats strip) and form panel; single-column mobile
  layout with centered brand mark. Self-contained grid centering so
  layout no longer depends on parent flex behavior. Drop the dead
  OnboardingModeSelector (it belongs to SetupPage, not login) and add
  loader spinner, animated submit arrow, and clearer error banner.
- StrategyMarketPage: replace the 560-line bespoke marketplace with a
  branded handoff to vergex.trade/explore. Direct iframe embedding is
  currently blocked by vergex's X-Frame-Options: SAMEORIGIN and
  frame-ancestors 'self', and there is no way to reliably detect the
  block from JavaScript (load event fires for the browser error page,
  contentWindow.location throws SecurityError in both success and
  failure). The component now renders a centered card with the
  POWERED BY VERGEX.TRADE pill, headline, description, gold CTA, and
  a stats row, with all three supported languages.
- .gitignore: exclude .gstack/ (local security audit reports).
2026-05-29 16:14:46 +08:00
tinkle-community
99361cb085 fix(security): harden auth flows and lock down telegram bot tool
- config: require JWT_SECRET >=32 bytes and reject the historical
  default fallback; MustInit aborts startup under an insecure config
- api: CORS now uses CORS_ALLOWED_ORIGINS allowlist with safe
  localhost defaults instead of returning Access-Control-Allow-Origin: *
- api: /api/reset-password and /api/reset-account stay public so
  recovery still works, but require an explicit confirm phrase in the
  body to block accidental and drive-by triggers
- api: drop adoptOrphanRecords so wiping the account no longer hands
  the next registrant the previous owner's wallet keys and exchange
  API credentials
- api: getTraderFromQuery now does a soft ownership check; equity-history
  is restricted to traders with show_in_competition=true and
  GetOrderFills joins on trader_id
- telegram: bot api_request tool uses a default-deny method+path
  allowlist so prompt injection cannot reach password, exchange key,
  AI provider or wallet endpoints
- ci: drop @master / @main on trivy-action and trufflehog; pin to
  released versions with a TODO to move to SHA + Dependabot
- web: reset flows send the required confirm phrase; "Forgot account"
  copy (en/zh/id) warns that wallet and exchange keys will be lost
- docker-compose: keep ./.env mount for onboarding wallet persistence
  with an inline note on the tradeoff, drop the host-exposed pprof port
2026-05-29 07:51:26 +08:00
tinklefund
3b2e7027db feat(web): refresh Hyperliquid-focused product UI
- Update landing, chart, settings, and data page copy for stock trading

- Adjust branding and translations around Hyperliquid positioning

- Extend frontend config types for the updated exchange settings
2026-05-25 01:25:23 +08:00
tinklefund
f4ee723aa2 feat(agent): surface Hyperliquid stock trading context
- Add stock symbol panel and agent chat page wiring

- Update onboarding and tool visibility for focused trader flows

- Tighten related tests around configuration and trader scope
2026-05-25 01:25:10 +08:00
tinklefund
5bdffee3b0 feat(strategy): support Hyperliquid stock strategy editing
- Extend strategy storage and engine analysis for Hyperliquid defaults

- Rework coin source and indicator editors for the stock strategy flow

- Update Strategy Studio translations and page wiring
2026-05-25 01:25:05 +08:00
tinklefund
c7c003cc3c feat(trader): wire Hyperliquid wallet and quick trade flow
- Add wallet API endpoints and exchange storage fields for Hyperliquid

- Normalize quick trade order paths, symbols, and builder fee coverage

- Add frontend wallet connect and quick trade helpers
2026-05-25 01:24:58 +08:00
tinklefund
f37fc9f887 feat(hyperliquid): add stock symbol market data support
- Add Hyperliquid/XYZ symbol normalization tests and backend coverage

- Extend kline and market data lookup paths for US stock symbols

- Wire frontend data API types for stock-oriented market requests
2026-05-25 01:24:49 +08:00
tinklefund
908fc09aca feat(strategy): replace default presets with Hyperliquid US stock strategies
Remove the old generic risk-profile defaults from the user strategy bootstrap path and replace them with concrete Hyperliquid USDC equity presets that can be selected directly when creating an AI trader.

Add three ready-to-run strategy presets: a volume-ranked US stock trend preset, a fixed mega-cap preset covering AAPL-USDC/MSFT-USDC/GOOGL-USDC/AMZN-USDC/META-USDC, and a gainers-ranked US stock breakout preset.

Normalize the presets to use Hyperliquid-native stock discovery instead of AI500/OI crypto-style sources, with conservative defaults for max positions, leverage, margin usage, confidence, risk-reward, and multi-timeframe indicators.

Make default strategy synchronization idempotent for existing users: remove obsolete unused legacy preset rows, backfill the new US stock presets, and avoid overriding an already active custom strategy.

Update the trader creation modal preview labels so Hyperliquid stock ranking and fixed US stock sources are described clearly when users select a strategy.

Add API tests covering the new preset set, legacy preset cleanup, idempotent sync behavior, and preservation of an existing active custom strategy.

Verified with: go test ./api ./store; npm run build; docker compose up -d --build nofx nofx-frontend; backend /api/health; frontend HTTP 200; compose health checks.
2026-05-25 01:20:05 +08:00
shinchan-zhai
d80bb31c0a fix(web): fix UI bugs and unify design tokens
- Add missing .nofx-glass CSS class (used in 20+ places but undefined)
- Fix Input component referencing undefined --brand-black/--brand-light-gray
- Unify background colors to #0B0E11 (was 3 different near-blacks)
- Switch body font from IBM Plex Mono to Inter for readability
- Improve chat bubble contrast (bg 0.03→0.05, border 0.05→0.08)
- Brighten timestamp (#2c2c42→#5a5a72) and disclaimer (#1e1e32→#4a4a62)
- Unify ::selection color to gold (was orange)
- Remove global button:hover translateY that conflicted with active:scale

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-11 23:51:27 +08:00
shinchan-zhai
9f25bf49bf fix(agent): use provider registry for claw402, echo reasoning_content for thinking models, add Beta badge
- Agent now uses mcp.NewAIClientByProvider() for claw402 provider, ensuring
  x402 payment signing works correctly instead of generic HTTP client
- Added ReasoningContent field to Message/LLMResponse structs and wired
  serialization/parsing so DeepSeek thinking models work in multi-turn
- Added Beta badge to Agent nav tab in HeaderBar

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-11 20:22:32 +08:00
shinchan-zhai
b8cde34e67 feat(agent): add NOFXi agent chat workflow (#1495)
- Add NOFXi agent backend: central brain, planner runtime, skill routing,
  memory/state handling, config validation, and action execution
- Add agent chat page with SSE streaming, step/status panels, and
  user preferences
- Extend trader/model/exchange/strategy APIs and store for agent-driven
  configuration
- Add stopCh guard in async maintenance goroutine to prevent leak on Stop()
- Add timeout context for trader diagnosis LLM calls
- Add TargetRef nil guards in all execute*Action handlers
- Add ensureHistory() for nil-safe history access

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-11 16:54:53 +08:00
shinchan-zhai
32e8a03a85 merge: resolve conflicts from origin/dev into PR #1495
- Use PR branch (dev-nofxi) as authority for agent/ module code
- Merge dev's newer model names (MiniMax-M2.7, deepseek-v4-flash)
  with PR's blockrun provider entries
- Fix duplicate agent init in main.go, keep defer-based Stop()
- Fix var type bug in store/ai_model.go (model → models)
- Remove dev-only test files incompatible with PR's evolved agent code
  (to be re-synced after merge)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-11 16:52:04 +08:00
lky-spec
e67a927a4f Refine strategy creation flow and diagnostics 2026-05-09 14:48:24 +08:00
lky-spec
0f11be77f8 Improve NOFXi agent strategy creation flow 2026-05-06 17:00:05 +08:00
lky-spec
159f27dfdd Improve NOFXi agent product handling 2026-05-02 22:55:10 +08:00
lky-spec
25d0b30ea9 Split strategy config by strategy type 2026-04-28 20:19:24 +08:00
lky-spec
d481b3d88c Remove local-only agent artifacts 2026-04-27 10:51:09 +08:00
shinchan-zhai
0d3b9536d5 merge: resolve conflicts from origin/main into dev
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>
2026-04-26 00:13:31 +08:00
shinchan-zhai
132fd93072 fix(agent,trader): guard nil TargetRef in skill handlers and fix toast indentation
- 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>
2026-04-26 00:00:26 +08:00
lky-spec
9ee931ee30 v2 2026-04-25 20:24:46 +08:00
lky-spec
c244e4cdf1 change v1 2026-04-25 16:18:45 +08:00
shinchan-zhai
4cadf6f442 fix(agent,claw402): harden agent runtime and strip max_tokens for thinking models
- 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>
2026-04-25 11:48:37 +08:00
deanokk
5dbe32d884 fix(trader): resolve conflict-related ModelConfigModal UI issues (#1493)
Co-authored-by: Dean <afei.wuhao@gmail.com>
2026-04-25 00:51:14 +08:00
deanokk
a20a71b88d feat(claw402): add DeepSeek V4 models and default to Flash (#1491)
* 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>
2026-04-24 17:35:30 +08:00
deanokk
3dbf5beece feat(payment): add new DeepSeek V4 models to claw402 endpoints and pricing (#1488)
- 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>
2026-04-24 14:44:28 +08:00
lky-spec
3ca95b294d feat: port NOFXi agent module onto latest dev base (#1485)
* feat: integrate NOFXi agent into dev

* Enhance NOFXi agent workflow and diagnostics
2026-04-21 23:47:55 +08:00
lky-spec
737f9bca95 Enhance NOFXi agent workflow and diagnostics 2026-04-19 16:06:28 +08:00
lky-spec
5c4e7502d7 feat: integrate NOFXi agent into dev 2026-04-18 16:06:42 +08:00
Lance
7ae5bf8247 release: merge dev into main (2026-04-17) (#1484)
* 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>
2026-04-17 19:13:35 +08:00
Lance
0a1a2923dc 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.
2026-04-17 11:17:17 +08:00
deanokk
e1b5a5d833 refactor: replace window.location with useNavigate for routing in auth components (#1470)
Co-authored-by: Dean <afei.wuhao@gmail.com>
2026-04-13 23:44:14 +08:00
Lance
c93ee337a7 release: model switching fix + active strategy deletion guard (#1465)
* 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>
2026-04-12 11:43:34 +08:00
shinchan-zhai
eef78b7987 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>
2026-04-12 11:42:14 +08:00
deanokk
a1af4fec58 feat(store): prevent deletion of active strategies and update translations (#1461)
Co-authored-by: Dean <afei.wuhao@gmail.com>
2026-04-11 01:09:13 +08:00
shinchan-zhai
6fe849c18d fix: update frontend default model references from DeepSeek to GLM
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>
2026-04-10 22:47:35 +08:00
shinchan-zhai
4f0a922779 feat: add "forgot account" reset flow with wallet preservation
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>
2026-04-10 18:00:56 +08:00
deanokk
80272c0d5a fix(dashboard): preserve trader selection in URL and silence background requests (#1459)
* 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>
2026-04-04 17:16:47 +08:00
shinchan-zhai
8a0f3f5a13 feat: change claw402 default model from deepseek to glm-5 2026-04-04 14:48:42 +08:00
Zavier
0c1f438cc3 fix: improve trader error feedback, stale balance cleanup, and claw402 warnings (#1452)
* fix: improve trader error handling and balance validation

* fix: localize structured trader failure reasons

---------

Co-authored-by: apple <apple@MacbookPro-zbh.local>
2026-04-01 22:10:29 +08:00
deanokk
9a80f1d88d feat: add exchange account states and refine beginner trader creation flow (#1450)
* 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>
2026-04-01 16:26:04 +08:00
Zavier
287280857b perf: reduce frontend login and dashboard friction (#1447)
Co-authored-by: apple <apple@MacbookPro-zbh.local>
2026-03-31 20:40:12 +08:00