Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
4292056
feat: update pool handlers to use network-based API
fengtality Apr 28, 2026
a58bb03
Refactor pools management to use network-first approach like tokens
fengtality Apr 28, 2026
bcc4423
Remove unnecessary gateway restart messages from pools
fengtality Apr 28, 2026
d01bf48
Add default networks feature for tokens and pools menus
fengtality Apr 28, 2026
39aa681
Add checkmark to default networks in networks menu
fengtality Apr 28, 2026
ee6a5ee
Use green checkmark emoji for default networks
fengtality Apr 28, 2026
08f1c11
fix(pools): improve pool pair display formatting
fengtality Apr 29, 2026
d73a1c1
feat(lp): add Orca pool listing support
fengtality Apr 29, 2026
281c329
fix: fix chart not showing and address display issues
fengtality Apr 29, 2026
a2fe586
fix: show full pool address in detail view for easy copying
fengtality Apr 29, 2026
ddb7a33
fix: set explicit Y-axis range for OHLCV chart based on price data
fengtality Apr 29, 2026
54aae34
Merge branch 'feat/unify_backend_layer' of github.com:hummingbot/cond…
fengtality Apr 30, 2026
0f47309
Merge branch 'main' of github.com:hummingbot/condor into feat/network…
fengtality May 5, 2026
e43d2a3
Add Orca/EVM DEX support, save endpoints, and wallet default management
fengtality May 6, 2026
e0ec421
Merge branch 'main' of github.com:hummingbot/condor into feat/network…
fengtality May 7, 2026
25b5d9e
feat(gateway): add RPC Providers menu for API keys and custom URLs
fengtality May 8, 2026
102a76d
fix(gateway): RPC providers input routing + LP position action fixes
fengtality May 8, 2026
8f31071
Merge branch 'main' of github.com:hummingbot/condor into feat/network…
fengtality May 9, 2026
8745d86
fix(gateway): improve nodeURL activation prompt wording
fengtality May 9, 2026
4fc15c6
fix(acp): use npx for Gemini and Copilot CLI commands
fengtality May 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions condor/acp/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@

ACP_COMMANDS: dict[str, str] = {
"claude-code": "claude-agent-acp",
"gemini": "gemini --experimental-acp",
"copilot": "copilot --acp",
"gemini": "npx @google/gemini-cli --acp",
"copilot": "npx @github/copilot --acp --stdio",
"codex": "npx @zed-industries/codex-acp"
}

Expand Down
8 changes: 8 additions & 0 deletions handlers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,14 @@ def clear_all_input_states(context: ContextTypes.DEFAULT_TYPE) -> None:
context.user_data.pop("awaiting_token_input", None)
context.user_data.pop("token_network", None)

# Gateway - RPC provider states
context.user_data.pop("awaiting_rpc_input", None)
context.user_data.pop("rpc_message_id", None)
context.user_data.pop("rpc_chat_id", None)
context.user_data.pop("rpc_url_network_list", None)
context.user_data.pop("rpc_edit_network_id", None)
context.user_data.pop("rpc_edit_network_idx", None)

# Bots - controller config states
context.user_data.pop("bots_state", None)
context.user_data.pop("controller_config_params", None)
Expand Down
1 change: 1 addition & 0 deletions handlers/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ async def handle_all_text_input(update: Update, context: ContextTypes.DEFAULT_TY
or context.user_data.get("awaiting_network_input")
or context.user_data.get("awaiting_token_input")
or context.user_data.get("awaiting_pool_input")
or context.user_data.get("awaiting_rpc_input")
):
await handle_gateway_input(update, context)
return
Expand Down
7 changes: 7 additions & 0 deletions handlers/config/gateway/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ async def gateway_command(update: Update, context: ContextTypes.DEFAULT_TYPE) ->
show_networks_menu,
)
from .pools import handle_pool_action, handle_pool_input, show_pools_menu
from .rpc_providers import handle_rpc_action, handle_rpc_input, show_rpc_providers_menu
from .tokens import handle_token_action, handle_token_input, show_tokens_menu
from .wallets import handle_wallet_action, handle_wallet_input, show_wallets_menu

Expand Down Expand Up @@ -108,6 +109,10 @@ async def handle_gateway_callback(
await show_tokens_menu(query, context)
elif query.data.startswith("gateway_token_"):
await handle_token_action(query, context)
elif query.data == "gateway_rpc_providers":
await show_rpc_providers_menu(query, context)
elif query.data.startswith("gateway_rpc_"):
await handle_rpc_action(query, context)


async def handle_gateway_input(
Expand All @@ -127,6 +132,8 @@ async def handle_gateway_input(
await handle_network_config_input(update, context)
elif context.user_data.get("awaiting_connector_config"):
await handle_connector_config_input(update, context)
elif context.user_data.get("awaiting_rpc_input"):
await handle_rpc_input(update, context)


__all__ = [
Expand Down
40 changes: 40 additions & 0 deletions handlers/config/gateway/_shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,43 @@ def get_connector_networks(
"""
connector_info = connectors_data.get(connector_name, {})
return connector_info.get("networks", [])


async def get_default_networks(client) -> List[str]:
"""
Get combined default networks from solana and ethereum configs.

Fetches default_networks from solana-mainnet-beta and ethereum-mainnet
and returns the combined list of network IDs.

Args:
client: HummingbotAPIClient instance

Returns:
List of default network IDs (e.g., ['solana-mainnet-beta', 'ethereum-mainnet'])
"""
default_networks = []

# Check solana defaults
try:
solana_config = await client.gateway.get_network_config("solana-mainnet-beta")
solana_defaults = solana_config.get("default_networks", [])
for network in solana_defaults:
network_id = f"solana-{network}"
if network_id not in default_networks:
default_networks.append(network_id)
except Exception as e:
logger.debug(f"Could not fetch solana defaults: {e}")

# Check ethereum defaults
try:
eth_config = await client.gateway.get_network_config("ethereum-mainnet")
eth_defaults = eth_config.get("default_networks", [])
for network in eth_defaults:
network_id = f"ethereum-{network}"
if network_id not in default_networks:
default_networks.append(network_id)
except Exception as e:
logger.debug(f"Could not fetch ethereum defaults: {e}")

return default_networks
7 changes: 6 additions & 1 deletion handlers/config/gateway/menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,18 @@ async def show_gateway_menu(query, context: ContextTypes.DEFAULT_TYPE) -> None:
"🪙 Tokens", callback_data="gateway_tokens"
),
InlineKeyboardButton(
"📋 Logs", callback_data="gateway_logs"
"📡 RPC Providers", callback_data="gateway_rpc_providers"
),
],
[
InlineKeyboardButton(
"📋 Logs", callback_data="gateway_logs"
),
InlineKeyboardButton(
"🔄 Restart", callback_data="gateway_restart"
),
],
[
InlineKeyboardButton(
"⏹ Stop", callback_data="gateway_stop"
),
Expand Down
115 changes: 109 additions & 6 deletions handlers/config/gateway/networks.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from telegram.ext import ContextTypes

from ..user_preferences import get_active_server
from ._shared import escape_markdown_v2, extract_network_id, logger
from ._shared import escape_markdown_v2, extract_network_id, get_default_networks, logger


async def show_networks_menu(query, context: ContextTypes.DEFAULT_TYPE) -> None:
Expand Down Expand Up @@ -34,6 +34,9 @@ async def show_networks_menu(query, context: ContextTypes.DEFAULT_TYPE) -> None:
[InlineKeyboardButton("« Back", callback_data="config_gateway")]
]
else:
# Get default networks to highlight them
default_network_ids = await get_default_networks(client)

# Group networks by chain if possible
network_buttons = []
network_count = len(networks)
Expand All @@ -47,9 +50,14 @@ async def show_networks_menu(query, context: ContextTypes.DEFAULT_TYPE) -> None:
networks[:20]
): # Limit to first 20 to avoid message size issues
network_id = extract_network_id(network_item)
# Add checkmark if this is a default network
if network_id in default_network_ids:
label = f"✅ {network_id}"
else:
label = network_id
# Use index-based callback to avoid exceeding 64-byte limit
button = InlineKeyboardButton(
network_id, callback_data=f"gateway_network_view_{idx}"
label, callback_data=f"gateway_network_view_{idx}"
)
row.append(button)

Expand All @@ -63,9 +71,11 @@ async def show_networks_menu(query, context: ContextTypes.DEFAULT_TYPE) -> None:
network_buttons.append(row)

count_escaped = escape_markdown_v2(str(network_count))
default_count = len(default_network_ids)
message_text = (
f"🌍 *Networks* \\({count_escaped} available\\)\n\n"
"_Click on a network to view and configure settings\\._"
f"🌍 *Networks* \\({count_escaped} available, {default_count} default\\)\n\n"
"_Click on a network to view and configure settings\\._\n"
"_✅ indicates default networks shown in Tokens/Pools\\._"
)

keyboard = network_buttons + [
Expand Down Expand Up @@ -112,6 +122,10 @@ async def handle_network_action(query, context: ContextTypes.DEFAULT_TYPE) -> No
# Fallback for old-style callback data
network_id = network_idx_str
await show_network_details(query, context, network_id)
elif action_data.startswith("toggle_default_"):
# Toggle default network setting
network_id = action_data.replace("toggle_default_", "")
await toggle_default_network(query, context, network_id)
elif action_data == "config_cancel":
await handle_network_config_cancel(query, context)
else:
Expand Down Expand Up @@ -146,6 +160,15 @@ async def show_network_details(

network_escaped = escape_markdown_v2(network_id)

# Parse chain and network from network_id (e.g., "solana-mainnet-beta")
parts = network_id.split("-", 1)
chain = parts[0] if parts else network_id
network_name = parts[1] if len(parts) > 1 else ""

# Check if this network is in the default_networks list
default_networks = config_fields.get("default_networks", [])
is_default = network_name in default_networks if network_name else False

if not config_fields:
message_text = (
f"🌍 *Network: {network_escaped}*\n\n" "_No configuration available_"
Expand All @@ -154,15 +177,23 @@ async def show_network_details(
[InlineKeyboardButton("« Back", callback_data="gateway_networks")]
]
else:
# Build copyable config for editing
# Build copyable config for editing (exclude default_networks for display)
config_lines = []
for key, value in config_fields.items():
config_lines.append(f"{key}={value}")
if key != "default_networks":
config_lines.append(f"{key}={value}")

config_text = "\n".join(config_lines)

# Show default status
if is_default:
default_status = "✅ *Default Network* \\(shown in Tokens/Pools\\)"
else:
default_status = "⬜ _Not a default network_"

message_text = (
f"🌍 *{network_escaped}*\n\n"
f"{default_status}\n\n"
f"```\n{config_text}\n```\n\n"
f"✏️ _Send `key=value` to update_"
)
Expand All @@ -177,7 +208,19 @@ async def show_network_details(
context.user_data["network_message_id"] = query.message.message_id
context.user_data["network_chat_id"] = query.message.chat_id

# Toggle default button
if is_default:
toggle_text = "⬜ Remove from Defaults"
else:
toggle_text = "✅ Add to Defaults"

keyboard = [
[
InlineKeyboardButton(
toggle_text,
callback_data=f"gateway_network_toggle_default_{network_id}"
)
],
[InlineKeyboardButton("« Back", callback_data="gateway_networks")]
]

Expand Down Expand Up @@ -382,3 +425,63 @@ async def handle_network_config_cancel(
except Exception as e:
logger.error(f"Error handling cancel: {e}", exc_info=True)
await query.answer("Error cancelling configuration")


async def toggle_default_network(
query, context: ContextTypes.DEFAULT_TYPE, network_id: str
) -> None:
"""Toggle whether a network is in the default_networks list"""
try:
from config_manager import get_config_manager

await query.answer("Updating defaults...")

chat_id = query.message.chat_id
client = await get_config_manager().get_client_for_chat(
chat_id, preferred_server=get_active_server(context.user_data)
)

# Get current config
response = await client.gateway.get_network_config(network_id)
if isinstance(response, dict):
config = (
response.get("config", response) if "config" in response else response
)
else:
config = {}

# Parse network name from network_id (e.g., "solana-mainnet-beta" -> "mainnet-beta")
parts = network_id.split("-", 1)
network_name = parts[1] if len(parts) > 1 else network_id

# Get current default_networks list
default_networks = config.get("default_networks", [])
if not isinstance(default_networks, list):
default_networks = []

# Toggle
if network_name in default_networks:
# Remove from defaults
default_networks = [n for n in default_networks if n != network_name]
action = "removed from"
else:
# Add to defaults
default_networks.append(network_name)
action = "added to"

# Update the config
await client.gateway.update_network_config(
network_id,
{"default_networks": default_networks}
)

# Show success and refresh
network_escaped = escape_markdown_v2(network_id)
await query.answer(f"✅ {network_id} {action} defaults")

# Refresh the network details view
await show_network_details(query, context, network_id)

except Exception as e:
logger.error(f"Error toggling default network: {e}", exc_info=True)
await query.answer(f"❌ Error: {str(e)[:100]}")
Loading