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
This commit is contained in:
root
2026-04-17 10:57:42 +08:00
parent b9b0a52137
commit 802590c2b9
5 changed files with 115 additions and 45 deletions

View File

@@ -253,6 +253,43 @@ func (s *AIModelStore) Update(userID, id string, enabled bool, apiKey, customAPI
}
// Create creates an AI model
// ResolveClaw402WalletKey returns the claw402 wallet private key for a user.
// If preferredModelID is non-empty and points to a claw402 model, its key is returned first.
// Otherwise the first enabled claw402 model in the user's model list is used.
// Returns ("", nil) when no claw402 model is configured — callers should treat this as
// "no paid data routing" rather than an error.
func (s *AIModelStore) ResolveClaw402WalletKey(userID, preferredModelID string) (string, error) {
if preferredModelID != "" {
model, err := s.Get(userID, preferredModelID)
if err != nil {
return "", fmt.Errorf("failed to load selected AI model")
}
if model.Provider == "claw402" {
walletKey := string(model.APIKey)
if walletKey == "" {
return "", fmt.Errorf("selected claw402 model is missing wallet private key")
}
return walletKey, nil
}
}
models, err := s.List(userID)
if err != nil {
return "", fmt.Errorf("failed to load AI models")
}
for _, model := range models {
if model == nil || model.Provider != "claw402" {
continue
}
if walletKey := string(model.APIKey); walletKey != "" {
return walletKey, nil
}
}
return "", nil
}
func (s *AIModelStore) Create(userID, id, name, provider string, enabled bool, apiKey, customAPIURL string) error {
model := &AIModel{
ID: id,