Skip to content

Commit 5a3125e

Browse files
committed
ci: 💚 Add new CI
1 parent e0b57aa commit 5a3125e

File tree

4 files changed

+283
-30
lines changed

4 files changed

+283
-30
lines changed

.github/workflows/ci.yml

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
jobs:
8+
build:
9+
name: Build (uv)
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout
13+
uses: actions/checkout@v4
14+
- name: Setup uv and Python
15+
uses: astral-sh/setup-uv@v4
16+
with:
17+
enable-cache: true
18+
- name: Sync project dependencies (frozen)
19+
run: uv sync --frozen
20+
- name: Build package
21+
run: uv build
22+
23+
ruff:
24+
name: Ruff Format
25+
runs-on: ubuntu-latest
26+
steps:
27+
- name: Checkout
28+
uses: actions/checkout@v4
29+
- name: Setup uv and Python
30+
uses: astral-sh/setup-uv@v4
31+
with:
32+
enable-cache: true
33+
- name: Sync project dependencies (frozen)
34+
run: uv sync --frozen
35+
- name: Check formatting
36+
run: uv run ruff format --check .
37+
38+
mypy:
39+
name: Mypy Type Check
40+
runs-on: ubuntu-latest
41+
steps:
42+
- name: Checkout
43+
uses: actions/checkout@v4
44+
- name: Setup uv and Python
45+
uses: astral-sh/setup-uv@v4
46+
with:
47+
enable-cache: true
48+
- name: Sync project dependencies (frozen)
49+
run: uv sync --frozen
50+
- name: Type check
51+
run: uv run mypy
52+
53+
cli_help:
54+
name: CLI --help
55+
runs-on: ubuntu-latest
56+
steps:
57+
- name: Checkout
58+
uses: actions/checkout@v4
59+
- name: Setup uv and Python
60+
uses: astral-sh/setup-uv@v4
61+
with:
62+
enable-cache: true
63+
- name: Sync project dependencies (frozen)
64+
run: uv sync --frozen
65+
- name: Ensure CLI help succeeds
66+
run: uv run hlexec --help

README.md

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,47 @@
11
# HyperLiquid Executor
22

3-
43
## Usage
54

65
### Pre-requisites
76

8-
### Installation
9-
10-
### Commands
7+
Install `uv` via their official [docs](https://docs.astral.sh/uv/#installation). The one-liner is:
118

129
```sh
13-
# Deposit USDC from EVM (Arbitrum) to HL core
14-
hlexec deposit \
15-
--amount 10.5 \
16-
[--production] \
17-
[--rpc-url https://arb1.arbitrum.io/rpc] \
18-
[--usdc-address 0x...] \
19-
[--bridge-address 0x...]
10+
curl -LsSf https://astral.sh/uv/install.sh | sh
2011
```
2112

22-
#### `Status`
13+
> [!NOTE]
14+
> `uv` is highly recommended to use, other package managers are untested on this repo.
2315
24-
## Type Checking
16+
### Installation
2517

26-
This project uses mypy for static type checking. Configuration lives in `pyproject.toml` under `[tool.mypy]` with a `src/` layout (`mypy_path = "src"` and `files = ["hl_executor"]`).
18+
```sh
19+
uv sync
20+
```
2721

28-
Run mypy using your preferred workflow:
22+
### Commands
2923

30-
- With uv (after syncing dev deps):
31-
- `uv run mypy -p hl_executor`
32-
- or `uv run python -m mypy -p hl_executor`
24+
```sh
25+
Usage: hlexec [OPTIONS] COMMAND [ARGS]...
26+
27+
HyperLiquid Executor - Python CLI
28+
29+
Options:
30+
--private-key TEXT Private key for signing transactions
31+
--production Connect to the production environment (default is
32+
testnet)
33+
--address TEXT This the HL account address which the Action will be
34+
performed on
35+
--help Show this message and exit.
36+
37+
Commands:
38+
deposit Deposit Funds from EVM -> Core
39+
order Place Limit Order
40+
status Get positions and open orders for the account
41+
transfer Transfer funds between vaults
42+
withdraw Withdraw Funds from Core -> EVM
43+
```
3344

34-
- With an active virtualenv where mypy is installed:
35-
- `python -m mypy -p hl_executor`
36-
- or `mypy -p hl_executor`
45+
#### `status`
3746

38-
Notes:
39-
- Third‑party libs without type hints (e.g., `hyperliquid`, `web3`, `eth_account`) are silenced in config with per‑module ignores.
40-
- A `py.typed` marker is included so downstream users get type information when this package is distributed.
47+
#### `deposit <amount>`

src/handlers/constants.py

Lines changed: 133 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,138 @@
44
USDC_ARB_PROD_ADDR = "0xaf88d065e77c8cc2239327c5edb3a432268e5831"
55
USDC_ARB_TEST_ADDR = "0x1baabb04529d43a73232b713c0fe471f7c7334d5"
66

7-
87
HYPEREVM_TEST_RPC = "https://rpc.hyperliquid-testnet.xyz/evm"
98
HYPEREVM_PROD_RPC = "https://rpc.hyperliquid.xyz/evm"
9+
10+
ARB_TEST_RPC = "https://arbitrum-sepolia.therpc.io"
11+
ARB_PROD_RPC = "https://arb-one-mainnet.gateway.tatum.io"
12+
13+
14+
ERC20_ABI = [
15+
{
16+
"inputs": [],
17+
"name": "name",
18+
"outputs": [{"internalType": "string", "name": "", "type": "string"}],
19+
"stateMutability": "view",
20+
"type": "function",
21+
},
22+
{
23+
"inputs": [],
24+
"name": "symbol",
25+
"outputs": [{"internalType": "string", "name": "", "type": "string"}],
26+
"stateMutability": "view",
27+
"type": "function",
28+
},
29+
{
30+
"inputs": [],
31+
"name": "decimals",
32+
"outputs": [{"internalType": "uint8", "name": "", "type": "uint8"}],
33+
"stateMutability": "view",
34+
"type": "function",
35+
},
36+
{
37+
"inputs": [],
38+
"name": "totalSupply",
39+
"outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}],
40+
"stateMutability": "view",
41+
"type": "function",
42+
},
43+
{
44+
"inputs": [{"internalType": "address", "name": "account", "type": "address"}],
45+
"name": "balanceOf",
46+
"outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}],
47+
"stateMutability": "view",
48+
"type": "function",
49+
},
50+
{
51+
"inputs": [
52+
{"internalType": "address", "name": "owner", "type": "address"},
53+
{"internalType": "address", "name": "spender", "type": "address"},
54+
],
55+
"name": "allowance",
56+
"outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}],
57+
"stateMutability": "view",
58+
"type": "function",
59+
},
60+
{
61+
"inputs": [
62+
{"internalType": "address", "name": "spender", "type": "address"},
63+
{"internalType": "uint256", "name": "amount", "type": "uint256"},
64+
],
65+
"name": "approve",
66+
"outputs": [{"internalType": "bool", "name": "", "type": "bool"}],
67+
"stateMutability": "nonpayable",
68+
"type": "function",
69+
},
70+
{
71+
"inputs": [
72+
{"internalType": "address", "name": "to", "type": "address"},
73+
{"internalType": "uint256", "name": "amount", "type": "uint256"},
74+
],
75+
"name": "transfer",
76+
"outputs": [{"internalType": "bool", "name": "", "type": "bool"}],
77+
"stateMutability": "nonpayable",
78+
"type": "function",
79+
},
80+
{
81+
"inputs": [
82+
{"internalType": "address", "name": "from", "type": "address"},
83+
{"internalType": "address", "name": "to", "type": "address"},
84+
{"internalType": "uint256", "name": "amount", "type": "uint256"},
85+
],
86+
"name": "transferFrom",
87+
"outputs": [{"internalType": "bool", "name": "", "type": "bool"}],
88+
"stateMutability": "nonpayable",
89+
"type": "function",
90+
},
91+
{
92+
"anonymous": False,
93+
"inputs": [
94+
{
95+
"indexed": True,
96+
"internalType": "address",
97+
"name": "from",
98+
"type": "address",
99+
},
100+
{
101+
"indexed": True,
102+
"internalType": "address",
103+
"name": "to",
104+
"type": "address",
105+
},
106+
{
107+
"indexed": False,
108+
"internalType": "uint256",
109+
"name": "value",
110+
"type": "uint256",
111+
},
112+
],
113+
"name": "Transfer",
114+
"type": "event",
115+
},
116+
{
117+
"anonymous": False,
118+
"inputs": [
119+
{
120+
"indexed": True,
121+
"internalType": "address",
122+
"name": "owner",
123+
"type": "address",
124+
},
125+
{
126+
"indexed": True,
127+
"internalType": "address",
128+
"name": "spender",
129+
"type": "address",
130+
},
131+
{
132+
"indexed": False,
133+
"internalType": "uint256",
134+
"name": "value",
135+
"type": "uint256",
136+
},
137+
],
138+
"name": "Approval",
139+
"type": "event",
140+
},
141+
]

src/handlers/deposit.py

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,62 @@
1-
import click
21
from .setup import setup
3-
from .constants import HYPEREVM_PROD_RPC, HYPEREVM_TEST_RPC
2+
import click
3+
from .constants import (
4+
ARB_PROD_RPC,
5+
ARB_TEST_RPC,
6+
USDC_ARB_PROD_ADDR,
7+
USDC_ARB_TEST_ADDR,
8+
ERC20_ABI,
9+
BRIDGE2_PROD_ADDR,
10+
BRIDGE2_TEST_ADDR,
11+
)
412
from web3 import Web3, HTTPProvider
13+
from rich.console import Console
14+
from typing import Any
15+
from rich.table import Table
16+
from rich.text import Text
17+
from rich import box
518

619

720
def run(
821
production: bool, private_key: str | None, account_address: str | None, amount: str
922
) -> None:
23+
"""Deposit USDC to HyperCore from Arbitrum via signer wallet address"""
1024
info, exchange, address, account = setup(production, private_key, account_address)
11-
url = HYPEREVM_PROD_RPC if production else HYPEREVM_TEST_RPC
25+
url = ARB_PROD_RPC if production else ARB_TEST_RPC
1226
w3 = Web3(HTTPProvider(url))
13-
balance = w3.eth.get_balance(account.address)
14-
click.echo(f"Hello {account.address}, your balance is {balance}.")
27+
28+
usdc_address = (
29+
Web3.to_checksum_address(USDC_ARB_PROD_ADDR)
30+
if production
31+
else Web3.to_checksum_address(USDC_ARB_TEST_ADDR)
32+
)
33+
bridge_address = (
34+
Web3.to_checksum_address(BRIDGE2_PROD_ADDR)
35+
if production
36+
else Web3.to_checksum_address(BRIDGE2_TEST_ADDR)
37+
)
38+
39+
eth_balance = w3.eth.get_balance(account.address)
40+
usdc_contract = w3.eth.contract(address=usdc_address, abi=ERC20_ABI)
41+
usdc_balance = usdc_contract.functions.balanceOf(account.address).call()
42+
_renderHeader(eth_balance, usdc_balance)
43+
click.echo(f"Hello {account.address}, your balance is {eth_balance}.")
44+
click.echo(usdc_balance)
45+
46+
47+
def _renderHeader(ethBalance: Any, usdcBalance: Any) -> None:
48+
"""Render the header for the ETH statuses"""
49+
console = Console()
50+
table = Table(
51+
show_header=False,
52+
box=None,
53+
padding=(0, 1),
54+
title="Signer Balances",
55+
title_style="bold bright_cyan",
56+
title_justify="left",
57+
)
58+
table.add_column("k", style="bold cyan", no_wrap=True)
59+
table.add_column("v")
60+
table.add_row("ETH Balance", str(ethBalance))
61+
table.add_row("USDC Balance", str(usdcBalance))
62+
console.print(table)

0 commit comments

Comments
 (0)