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
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,16 @@ hyperliquid --keystore ~/.foundry/keystores/my-wallet ...
hyperliquid --private-key 0x... ... # avoid in shared shells / history
```

Bankr can also be used as an external signer for supported payloads. Bankr account setup and API-key creation happen outside this CLI; `hyperliquid` only uses the Bankr Wallet API to resolve the attached EVM wallet and request signatures.

```bash
export BANKR_API_KEY=bk_...
hyperliquid --bankr-signer default wallet address
hyperliquid --bankr-signer default --dry-run orders create --coin BTC --side buy --price 1 --size 0.001
```

Bankr support is intentionally fail-closed for raw Hyperliquid L1 action hashes until Bankr raw digest signing support is confirmed and verified. Use OWS, a keystore, stored local signing account, or explicit private key for live order/trading commands that require raw L1 signing.

Or set environment variables:

```bash
Expand All @@ -138,7 +148,7 @@ export OWS_PASSPHRASE=... # unlock encrypted OWS wallet

### Safety rules

- **Never** commit private keys, mnemonics, keystore files, OWS secrets, or config databases.
- **Never** commit private keys, mnemonics, keystore files, OWS secrets, Bankr API keys, or config databases.
- Prefer OWS wallets or keystores over raw `--private-key` flags in shared environments.
- Use API wallets when delegating trading to scripts or agents — they can't withdraw funds.
- `--testnet` is one flag away whenever you want to rehearse a flow before going live.
Expand Down
57 changes: 57 additions & 0 deletions examples/bankr_live_smoke.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use alloy::dyn_abi::TypedData;
use hyperliquid_cli::bankr;
use hyperliquid_cli::signing::SelectedSigner;
use hypersdk::hypercore::Chain;
use hypersdk::hypercore::api::UpdateLeverage;
use hypersdk::hypercore::types::Action;

fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = bankr::resolve_selector("default")?;
println!("wallet_address={}", config.address());

let signer = SelectedSigner::bankr(config.clone());
let err = signer
.sign_l1_action_sync(
Action::UpdateLeverage(UpdateLeverage {
asset: 0,
is_cross: true,
leverage: 2,
}),
1_777_963_000_000,
None,
Chain::Testnet,
)
.unwrap_err();
assert_eq!(err.exit_code(), 13);
println!("raw_l1_fail_closed_ok=true");

let typed_data: TypedData = serde_json::from_value(serde_json::json!({
"types": {
"EIP712Domain": [
{"name": "name", "type": "string"},
{"name": "chainId", "type": "uint256"}
],
"BankrCliSmoke": [
{"name": "message", "type": "string"},
{"name": "nonce", "type": "uint256"}
]
},
"primaryType": "BankrCliSmoke",
"domain": {
"name": "Hyperliquid CLI Bankr Smoke",
"chainId": "0x3e7"
},
"message": {
"message": "bankr signing smoke",
"nonce": "0x1"
}
}))?;

let _typed_signature = bankr::sign_typed_data(&config, &typed_data)?;
println!("typed_data_signature_ok=true");

let _message_signature = bankr::sign_message(&config, b"hyperliquid-cli bankr live smoke")?;
println!("personal_sign_signature_ok=true");

Ok(())
}
5 changes: 5 additions & 0 deletions src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ pub fn resolve_signer_with_account_and_ows(
resolve_stored_default_signer()
}

pub fn resolve_bankr_signer(selector: &str) -> Result<ResolvedSigner, anyhow::Error> {
let bankr = crate::bankr::resolve_selector(selector)?;
Ok(ResolvedSigner::new(SelectedSigner::bankr(bankr)))
}

pub fn resolve_stored_account_signer(selector: &str) -> Result<ResolvedSigner, anyhow::Error> {
// Try OWS first: selector may be an OWS wallet name or id.
let vault_path = crate::ows::ows_vault_path();
Expand Down
Loading
Loading