From 5bf524d646ff4c0353e823ecaab562c6243c4657 Mon Sep 17 00:00:00 2001 From: MXD66 <239960619+MXD66@users.noreply.github.com> Date: Fri, 5 Dec 2025 16:11:05 +0800 Subject: [PATCH 1/4] Update: standardize placeholder text for exchange API credentials standardize placeholder text for exchange API credentials --- .../valuecell/form/exchange-form.tsx | 71 +++++++++++++++++-- 1 file changed, 66 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/valuecell/form/exchange-form.tsx b/frontend/src/components/valuecell/form/exchange-form.tsx index 96c01effc..a72cd4eb0 100644 --- a/frontend/src/components/valuecell/form/exchange-form.tsx +++ b/frontend/src/components/valuecell/form/exchange-form.tsx @@ -42,6 +42,52 @@ export const EXCHANGE_OPTIONS = [ }, ]; +const getPlaceholder = ( + exchangeId: string, + fieldType: "api_key" | "secret_key" | "passphrase" | "wallet_address" | "private_key" +): string => { + switch (exchangeId) { + case "binance": + if (fieldType === "api_key") return "Enter API Key (64 characters)"; + if (fieldType === "secret_key") return "Enter Secret Key (64 characters)"; + break; + case "okx": + if (fieldType === "api_key") return "Enter API Key (Format: xxxxxxxx-xxxx-...)"; + if (fieldType === "secret_key") return "Enter Secret Key (32 uppercase letters & numbers)"; + if (fieldType === "passphrase") return "Enter Passphrase (Set during API creation)"; + break; + case "gate": + if (fieldType === "api_key") return "Enter API Key (Starts with 'key_')"; + if (fieldType === "secret_key") return "Enter Secret Key (64 characters)"; + break; + case "hyperliquid": + if (fieldType === "wallet_address") return "Enter Wallet Address (Starts with '0x')"; + if (fieldType === "private_key") return "Enter Private Key (64 characters)"; + break; + case "blockchaincom": + if (fieldType === "api_key") return "Enter API Key (Format: xxxxxxxx-xxxx-...)"; + if (fieldType === "secret_key") return "Enter Secret Key"; + break; + case "coinbaseexchange": + if (fieldType === "api_key") return "Enter API Key (or Key Name)"; + if (fieldType === "secret_key") return "Enter API Secret (or Private Key)"; + if (fieldType === "passphrase") return "Enter Passphrase (Required for Legacy Pro API)"; + break; + case "mexc": + if (fieldType === "api_key") return "Enter Access Key (Starts with 'mx0')"; + if (fieldType === "secret_key") return "Enter Secret Key (Usually 32 characters)"; + break; + } + + // Default placeholders + if (fieldType === "api_key") return "Paste your API Key here"; + if (fieldType === "secret_key") return "Paste your Secret Key here"; + if (fieldType === "passphrase") return "Enter Passphrase"; + if (fieldType === "wallet_address") return "Enter Wallet Address"; + if (fieldType === "private_key") return "Enter Private Key"; + return ""; +}; + export const ExchangeForm = withForm({ defaultValues: { trading_mode: "live" as "live" | "virtual", @@ -144,7 +190,10 @@ export const ExchangeForm = withForm({ {(field) => ( )} @@ -152,7 +201,10 @@ export const ExchangeForm = withForm({ {(field) => ( )} @@ -163,7 +215,10 @@ export const ExchangeForm = withForm({ {(field) => ( )} @@ -171,7 +226,10 @@ export const ExchangeForm = withForm({ {(field) => ( )} @@ -182,7 +240,10 @@ export const ExchangeForm = withForm({ {(field) => ( )} From 9e85e27a03336022ff36d5f92cfc5d9a8bb81f44 Mon Sep 17 00:00:00 2001 From: MXD66 <239960619+MXD66@users.noreply.github.com> Date: Fri, 5 Dec 2025 16:28:43 +0800 Subject: [PATCH 2/4] feat: standardize placeholder text for exchange API credentials standardize placeholder text for exchange API credentials --- .../valuecell/form/exchange-form.tsx | 47 ++++++++++++------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/frontend/src/components/valuecell/form/exchange-form.tsx b/frontend/src/components/valuecell/form/exchange-form.tsx index a72cd4eb0..e4886b8cf 100644 --- a/frontend/src/components/valuecell/form/exchange-form.tsx +++ b/frontend/src/components/valuecell/form/exchange-form.tsx @@ -44,7 +44,12 @@ export const EXCHANGE_OPTIONS = [ const getPlaceholder = ( exchangeId: string, - fieldType: "api_key" | "secret_key" | "passphrase" | "wallet_address" | "private_key" + fieldType: + | "api_key" + | "secret_key" + | "passphrase" + | "wallet_address" + | "private_key", ): string => { switch (exchangeId) { case "binance": @@ -52,30 +57,40 @@ const getPlaceholder = ( if (fieldType === "secret_key") return "Enter Secret Key (64 characters)"; break; case "okx": - if (fieldType === "api_key") return "Enter API Key (Format: xxxxxxxx-xxxx-...)"; - if (fieldType === "secret_key") return "Enter Secret Key (32 uppercase letters & numbers)"; - if (fieldType === "passphrase") return "Enter Passphrase (Set during API creation)"; + if (fieldType === "api_key") + return "Enter API Key (Format: xxxxxxxx-xxxx-...)"; + if (fieldType === "secret_key") + return "Enter Secret Key (32 uppercase letters & numbers)"; + if (fieldType === "passphrase") + return "Enter Passphrase (Set during API creation)"; break; case "gate": if (fieldType === "api_key") return "Enter API Key (Starts with 'key_')"; if (fieldType === "secret_key") return "Enter Secret Key (64 characters)"; break; case "hyperliquid": - if (fieldType === "wallet_address") return "Enter Wallet Address (Starts with '0x')"; - if (fieldType === "private_key") return "Enter Private Key (64 characters)"; + if (fieldType === "wallet_address") + return "Enter Wallet Address (Starts with '0x')"; + if (fieldType === "private_key") + return "Enter Private Key (64 characters)"; break; case "blockchaincom": - if (fieldType === "api_key") return "Enter API Key (Format: xxxxxxxx-xxxx-...)"; + if (fieldType === "api_key") + return "Enter API Key (Format: xxxxxxxx-xxxx-...)"; if (fieldType === "secret_key") return "Enter Secret Key"; break; case "coinbaseexchange": if (fieldType === "api_key") return "Enter API Key (or Key Name)"; - if (fieldType === "secret_key") return "Enter API Secret (or Private Key)"; - if (fieldType === "passphrase") return "Enter Passphrase (Required for Legacy Pro API)"; + if (fieldType === "secret_key") + return "Enter API Secret (or Private Key)"; + if (fieldType === "passphrase") + return "Enter Passphrase (Required for Legacy Pro API)"; break; case "mexc": - if (fieldType === "api_key") return "Enter Access Key (Starts with 'mx0')"; - if (fieldType === "secret_key") return "Enter Secret Key (Usually 32 characters)"; + if (fieldType === "api_key") + return "Enter Access Key (Starts with 'mx0')"; + if (fieldType === "secret_key") + return "Enter Secret Key (Usually 32 characters)"; break; } @@ -192,7 +207,7 @@ export const ExchangeForm = withForm({ label="Wallet Address" placeholder={getPlaceholder( exchangeId || "", - "wallet_address" + "wallet_address", )} /> )} @@ -203,7 +218,7 @@ export const ExchangeForm = withForm({ label="Private Key" placeholder={getPlaceholder( exchangeId || "", - "private_key" + "private_key", )} /> )} @@ -217,7 +232,7 @@ export const ExchangeForm = withForm({ label="API Key" placeholder={getPlaceholder( exchangeId || "", - "api_key" + "api_key", )} /> )} @@ -228,7 +243,7 @@ export const ExchangeForm = withForm({ label="Secret Key" placeholder={getPlaceholder( exchangeId || "", - "secret_key" + "secret_key", )} /> )} @@ -242,7 +257,7 @@ export const ExchangeForm = withForm({ label="Passphrase" placeholder={getPlaceholder( exchangeId || "", - "passphrase" + "passphrase", )} /> )} From a61fd392dba7b62433b2c4eb797115292192c3fd Mon Sep 17 00:00:00 2001 From: MXD66 <239960619+MXD66@users.noreply.github.com> Date: Wed, 10 Dec 2025 17:44:38 +0800 Subject: [PATCH 3/4] =?UTF-8?q?Update=EF=BC=9AUpdate=20API=20connection=20?= =?UTF-8?q?failed=20error=20message?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updated the error message displayed when an API connection fails to be more descriptive and helpful to users. --- frontend/src/components/valuecell/form/exchange-form.tsx | 2 +- python/valuecell/server/api/routers/strategy_agent.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/valuecell/form/exchange-form.tsx b/frontend/src/components/valuecell/form/exchange-form.tsx index e4886b8cf..88a8cb628 100644 --- a/frontend/src/components/valuecell/form/exchange-form.tsx +++ b/frontend/src/components/valuecell/form/exchange-form.tsx @@ -128,7 +128,7 @@ export const ExchangeForm = withForm({ } catch (_error) { setTestStatus({ success: false, - message: "Failed, please check your API key", + message: "Connection failed. Please check your API Key, Secret Key, or Passphrase.", }); } }; diff --git a/python/valuecell/server/api/routers/strategy_agent.py b/python/valuecell/server/api/routers/strategy_agent.py index ec0aa6ac3..ecad9ab55 100644 --- a/python/valuecell/server/api/routers/strategy_agent.py +++ b/python/valuecell/server/api/routers/strategy_agent.py @@ -282,7 +282,7 @@ async def test_exchange_connection(request: ExchangeConfig): # But SuccessResponse implies 200. # If I raise HTTPException it shows as error. raise HTTPException( - status_code=400, detail="Failed, please check your API key" + status_code=400, detail="Connection failed. Please check your API Key, Secret Key, or Passphrase." ) finally: await gateway.close() @@ -291,7 +291,7 @@ async def test_exchange_connection(request: ExchangeConfig): # If create_ccxt_gateway fails or other error, avoid logging sensitive info logger.warning("Connection test failed") raise HTTPException( - status_code=400, detail="Failed, please check your API key" + status_code=400, detail="Connection failed. Please check your API Key, Secret Key, or Passphrase." ) @router.delete("/delete") From 3f5f77dfcc79fa53dbbae85e2554f3567124ec64 Mon Sep 17 00:00:00 2001 From: MXD66 <239960619+MXD66@users.noreply.github.com> Date: Wed, 10 Dec 2025 18:15:24 +0800 Subject: [PATCH 4/4] feat(ui): improve API connection error message clarity updated the error message displayed when an API connection fails to be more descriptive and helpful to users. --- .../src/components/valuecell/form/exchange-form.tsx | 4 +++- .../valuecell/server/api/routers/strategy_agent.py | 12 ++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/valuecell/form/exchange-form.tsx b/frontend/src/components/valuecell/form/exchange-form.tsx index 88a8cb628..be76d3dfe 100644 --- a/frontend/src/components/valuecell/form/exchange-form.tsx +++ b/frontend/src/components/valuecell/form/exchange-form.tsx @@ -128,7 +128,9 @@ export const ExchangeForm = withForm({ } catch (_error) { setTestStatus({ success: false, - message: "Connection failed. Please check your API Key, Secret Key, or Passphrase.", + message: + "Connection failed. Please check your API Key, Secret Key, or " + + "Passphrase.", }); } }; diff --git a/python/valuecell/server/api/routers/strategy_agent.py b/python/valuecell/server/api/routers/strategy_agent.py index ecad9ab55..4acc78992 100644 --- a/python/valuecell/server/api/routers/strategy_agent.py +++ b/python/valuecell/server/api/routers/strategy_agent.py @@ -282,7 +282,11 @@ async def test_exchange_connection(request: ExchangeConfig): # But SuccessResponse implies 200. # If I raise HTTPException it shows as error. raise HTTPException( - status_code=400, detail="Connection failed. Please check your API Key, Secret Key, or Passphrase." + status_code=400, + detail=( + "Connection failed. Please check your API Key, " + "Secret Key, or Passphrase." + ), ) finally: await gateway.close() @@ -291,7 +295,11 @@ async def test_exchange_connection(request: ExchangeConfig): # If create_ccxt_gateway fails or other error, avoid logging sensitive info logger.warning("Connection test failed") raise HTTPException( - status_code=400, detail="Connection failed. Please check your API Key, Secret Key, or Passphrase." + status_code=400, + detail=( + "Connection failed. Please check your API Key, " + "Secret Key, or Passphrase." + ), ) @router.delete("/delete")