Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ The Hummingbot codebase is free and publicly available under the Apache 2.0 open
* [Installation](https://hummingbot.org/installation/): Install Hummingbot on various platforms
* [Discord](https://discord.gg/hummingbot): The main gathering spot for the global Hummingbot community
* [YouTube](https://www.youtube.com/c/hummingbot): Videos that teach you how to get the most out of Hummingbot
* [Spotify Podcast - The Bot Pod](https://open.spotify.com/show/1muzSO0SZqYBVQu2DXzGB1?si=ae9a9c0674c64b45): Weekly livestream and podcast by Hummingbot maintainers
* [Twitter](https://twitter.com/_hummingbot): Get the latest announcements about Hummingbot
* [Reported Volumes](https://p.datadoghq.com/sb/a96a744f5-a15479d77992ccba0d23aecfd4c87a52): Reported trading volumes across all Hummingbot instances
* [Reported Volumes](https://reporting.hummingbot.org/): Reported trading volumes across all Hummingbot instances
* [Newsletter](https://hummingbot.substack.com): Get our newsletter whenever we ship a new release

## Getting Started
Expand Down Expand Up @@ -49,6 +50,22 @@ make deploy
docker attach hummingbot
```

### Install Hummingbot from Source

Clone the repo, install dependencies, and run Hummingbot directly from source:

```bash
# Clone the repository
git clone https://github.com/hummingbot/hummingbot.git
cd hummingbot

# Install from source
make install

# Run Hummingbot
make run
```

### Install Hummingbot + Gateway DEX Middleware

Gateway provides standardized connectors for interacting with automatic market maker (AMM) decentralized exchanges (DEXs) across different blockchain networks.
Expand Down Expand Up @@ -137,7 +154,10 @@ Currently, the master branch of Hummingbot also includes the following exchange
| Exchange | Type | Sub-Type(s) | Connector ID(s) | Discount |
|------|------|------|-------|----------|
| [0x Protocol](https://hummingbot.org/exchanges/gateway/0x/) | AMM DEX | Router | `0x` | - |
| [Aevo](https://hummingbot.org/exchanges/aevo/) | CLOB CEX | Perpetual | `aevo_perpetual` | - |
| [Architect](https://hummingbot.org/exchanges/architect/) | CLOB CEX | Perpetual | `architect_perpetual` | - |
| [AscendEx](https://hummingbot.org/exchanges/ascendex/) | CLOB CEX | Spot | `ascend_ex` | - |
| [Backpack](https://hummingbot.org/exchanges/backpack/) | CLOB CEX | Spot, Perpetual | `backpack`, `backpack_perpetual` | - |
| [Balancer](https://hummingbot.org/exchanges/gateway/balancer/) | AMM DEX | AMM | `balancer` | - |
| [BingX](https://hummingbot.org/exchanges/bing_x/) | CLOB CEX | Spot | `bing_x` | - |
| [Bitrue](https://hummingbot.org/exchanges/bitrue/) | CLOB CEX | Spot | `bitrue` | - |
Expand All @@ -147,12 +167,18 @@ Currently, the master branch of Hummingbot also includes the following exchange
| [Coinbase](https://hummingbot.org/exchanges/coinbase/) | CLOB CEX | Spot | `coinbase_advanced_trade` | - |
| [Cube](https://hummingbot.org/exchanges/cube/) | CLOB CEX | Spot | `cube` | - |
| [Curve](https://hummingbot.org/exchanges/gateway/curve/) | AMM DEX | AMM | `curve` | - |
| [Decibel](https://hummingbot.org/exchanges/decibel/) | CLOB CEX | Perpetual | `decibel_perpetual` | - |
| [Dexalot](https://hummingbot.org/exchanges/dexalot/) | CLOB DEX | Spot | `dexalot` | - |
| [EVEDEX](https://hummingbot.org/exchanges/evedex/) | CLOB CEX | Perpetual | `evedex_perpetual` | - |
| [Foxbit](https://hummingbot.org/exchanges/foxbit/) | CLOB CEX | Spot | `foxbit` | - |
| [GRVT](https://hummingbot.org/exchanges/grvt/) | CLOB CEX | Perpetual | `grvt_perpetual` | - |
| [Injective Helix](https://hummingbot.org/exchanges/injective/) | CLOB DEX | Spot, Perpetual | `injective_v2`, `injective_v2_perpetual` | - |
| [Jupiter](https://hummingbot.org/exchanges/gateway/jupiter/) | AMM DEX | Router | `jupiter` | - |
| [Kraken](https://hummingbot.org/exchanges/kraken/) | CLOB CEX | Spot | `kraken` | - |
| [Meteora](https://hummingbot.org/exchanges/gateway/meteora/) | AMM DEX | CLMM | `meteora` | - |
| [MEXC](https://hummingbot.org/exchanges/mexc/) | CLOB CEX | Spot | `mexc` | - |
| [NDAX](https://hummingbot.org/exchanges/ndax/) | CLOB CEX | Spot | `ndax` | - |
| [Pacifica](https://hummingbot.org/exchanges/pacifica/) | CLOB CEX | Perpetual | `pacifica_perpetual` | - |
| [PancakeSwap](https://hummingbot.org/exchanges/gateway/pancakeswap/) | AMM DEX | AMM | `pancakeswap` | - |
| [QuickSwap](https://hummingbot.org/exchanges/gateway/quickswap/) | AMM DEX | AMM | `quickswap` | - |
| [Raydium](https://hummingbot.org/exchanges/gateway/raydium/) | AMM DEX | AMM, CLMM | `raydium` | - |
Expand Down
8 changes: 5 additions & 3 deletions hummingbot/client/command/balance_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import pandas as pd

from hummingbot.client.config.config_validators import validate_decimal, validate_exchange
from hummingbot.client.config.config_validators import validate_decimal, validate_derivative, validate_exchange
from hummingbot.client.performance import PerformanceMetrics
from hummingbot.client.settings import AllConnectorSettings
from hummingbot.core.rate_oracle.rate_oracle import RateOracle
Expand Down Expand Up @@ -40,11 +40,13 @@ def balance(self, # type: HummingbotApplication
if args is None or len(args) == 0:
safe_ensure_future(self.show_asset_limits())
return
if len(args) != 3 or validate_exchange(args[0]) is not None or validate_decimal(args[2]) is not None:
exchange = args[0].lower() if len(args) > 0 else ""
is_invalid_exchange = validate_exchange(exchange) is not None
is_invalid_derivative = validate_derivative(exchange) is not None
if len(args) != 3 or (is_invalid_exchange and is_invalid_derivative) or validate_decimal(args[2]) is not None:
self.notify("Error: Invalid command arguments")
self.notify_balance_limit_set()
return
exchange = args[0]
asset = args[1].upper()
amount = float(args[2])
if balance_asset_limit.get(exchange) is None:
Expand Down
62 changes: 53 additions & 9 deletions hummingbot/client/command/connect_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
if not cs.use_ethereum_wallet and not cs.uses_gateway_generic_connector() if cs.name != "probit_kr"}


def _lighter_account_index(api_keys: Dict[str, str]) -> Optional[str]:
"""Return the account index from stored Lighter credentials, used as a fallback identifier."""
return next((v for k, v in api_keys.items() if "account_index" in k and v), None)


class ConnectCommand:
def connect(self, # type: HummingbotApplication
option: str):
Expand All @@ -41,20 +46,43 @@ async def connect_exchange(self, # type: HummingbotApplication
connector_config = ClientConfigAdapter(AllConnectorSettings.get_connector_config_keys(connector_name))
if Security.connector_config_file_exists(connector_name):
await Security.wait_til_decryption_done()
api_key_config = [value for key, value in Security.api_keys(connector_name).items() if "api_key" in key]
if api_key_config:
api_key = api_key_config[0]
prompt = (
f"Would you like to replace your existing {connector_name} API key {api_key} (Yes/No)? >>> "
)
stored_keys = Security.api_keys(connector_name)
# For Lighter connectors, show the derived public address rather than the key index.
is_lighter = connector_name.startswith("lighter")
if is_lighter:
from hummingbot.connector.lighter_common.lighter_key_utils import fetch_lighter_public_key
acct_idx = stored_keys.get(f"{connector_name}_account_index") or ""
key_idx = stored_keys.get(f"{connector_name}_api_key_index") or ""
public_key = await fetch_lighter_public_key(connector_name, acct_idx, key_idx)
if public_key:
prompt = (
f"Would you like to replace your existing {connector_name} key "
f"(public key: {public_key}) (Yes/No)? >>> "
)
else:
account_id = _lighter_account_index(stored_keys)
if account_id:
prompt = (
f"Would you like to replace your existing {connector_name} key "
f"(account index: {account_id}) (Yes/No)? >>> "
)
else:
prompt = f"Would you like to replace your existing {connector_name} key (Yes/No)? >>> "
else:
prompt = f"Would you like to replace your existing {connector_name} key (Yes/No)? >>> "
api_key_config = [v for k, v in stored_keys.items() if "api_key" in k]
if api_key_config:
prompt = (
f"Would you like to replace your existing {connector_name} API key "
f"{api_key_config[0]} (Yes/No)? >>> "
)
else:
prompt = f"Would you like to replace your existing {connector_name} key (Yes/No)? >>> "
answer = await self.app.prompt(prompt=prompt)
if self.app.to_stop_config:
self.app.to_stop_config = False
return
if answer.lower() in ("yes", "y"):
previous_keys = Security.api_keys(connector_name)
previous_keys = stored_keys
await self._perform_connect(connector_config, previous_keys)
else:
await self._perform_connect(connector_config)
Expand Down Expand Up @@ -138,7 +166,23 @@ async def _perform_connect(self, connector_config: ClientConfigAdapter, previous
Security.update_secure_config(connector_config)
err_msg = await self.validate_n_connect_connector(connector_name)
if err_msg is None:
self.notify(f"\nYou are now connected to {connector_name}.")
if connector_name.startswith("lighter"):
from hummingbot.connector.lighter_common.lighter_key_utils import fetch_lighter_public_key
new_keys = Security.api_keys(connector_name)
acct_idx = new_keys.get(f"{connector_name}_account_index") or ""
key_idx = new_keys.get(f"{connector_name}_api_key_index") or ""
public_key = await fetch_lighter_public_key(connector_name, acct_idx, key_idx)
if public_key:
self.notify(f"\nYou are now connected to {connector_name} (public key: {public_key}).")
else:
account_id = _lighter_account_index(new_keys)
msg = (
f"\nYou are now connected to {connector_name} (account index: {account_id})."
if account_id else f"\nYou are now connected to {connector_name}."
)
self.notify(msg)
else:
self.notify(f"\nYou are now connected to {connector_name}.")
safe_ensure_future(TradingPairFetcher.get_instance(client_config_map=ClientConfigAdapter).fetch_all(client_config_map=ClientConfigAdapter))
else:
self.notify(f"\nError: {err_msg}")
Expand Down
Empty file.
2 changes: 2 additions & 0 deletions hummingbot/connector/derivative/lighter_perpetual/dummy.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cdef class dummy():
pass
2 changes: 2 additions & 0 deletions hummingbot/connector/derivative/lighter_perpetual/dummy.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cdef class dummy():
pass
Loading
Loading