From 4884e40372b7ef1a0714c8c1b22526cd764e6c4d Mon Sep 17 00:00:00 2001 From: Sayo <82053242+wtfsayo@users.noreply.github.com> Date: Wed, 20 May 2026 23:57:50 +0530 Subject: [PATCH 1/3] Add Bankr signer support --- Cargo.lock | 1 + Cargo.toml | 2 +- README.md | 12 +- examples/bankr_live_smoke.rs | 57 ++ src/auth.rs | 5 + src/bankr.rs | 694 ++++++++++++++++++ src/cli_runtime.rs | 16 +- src/command_catalog.json | 336 ++++++--- src/command_metadata.rs | 22 + src/command_registry.rs | 34 + src/commands/schema.rs | 2 + src/commands/wallet.rs | 21 +- src/lib.rs | 1 + src/main.rs | 13 +- src/resolvers.rs | 6 + src/signing.rs | 60 ++ .../contracts/registry_inventory.json | 336 ++++++--- .../contracts/schema_high_risk_metadata.json | 168 +++-- .../contracts/schema_representative.json | 36 +- tests/registry_contracts.rs | 4 + tests/release_artifacts.rs | 1 + tests/schema_contracts.rs | 1 + 22 files changed, 1526 insertions(+), 302 deletions(-) create mode 100644 examples/bankr_live_smoke.rs create mode 100644 src/bankr.rs diff --git a/Cargo.lock b/Cargo.lock index a018e54..99f4c13 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5289,6 +5289,7 @@ dependencies = [ "base64 0.22.1", "bytes", "encoding_rs", + "futures-channel", "futures-core", "futures-util", "h2", diff --git a/Cargo.toml b/Cargo.toml index f8c3d65..d64fcdd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ path = "src/main.rs" [dependencies] # Primary SDK for Hyperliquid API hypersdk = "0.2" -reqwest = { version = "0.13", features = ["json"] } +reqwest = { version = "0.13", features = ["blocking", "json"] } alloy-signer-local = { version = "2.0.4", features = ["keystore"] } # hypersdk 0.2 still re-exports Alloy 1.x signer types. Keep the v1 crates # feature-enabled until hypersdk moves to Alloy 2 so local keystores and diff --git a/README.md b/README.md index 626490d..8c2c6e2 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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. diff --git a/examples/bankr_live_smoke.rs b/examples/bankr_live_smoke.rs new file mode 100644 index 0000000..8da0ed3 --- /dev/null +++ b/examples/bankr_live_smoke.rs @@ -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> { + 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(()) +} diff --git a/src/auth.rs b/src/auth.rs index 78f491b..368bc50 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -121,6 +121,11 @@ pub fn resolve_signer_with_account_and_ows( resolve_stored_default_signer() } +pub fn resolve_bankr_signer(selector: &str) -> Result { + let bankr = crate::bankr::resolve_selector(selector)?; + Ok(ResolvedSigner::new(SelectedSigner::bankr(bankr))) +} + pub fn resolve_stored_account_signer(selector: &str) -> Result { // Try OWS first: selector may be an OWS wallet name or id. let vault_path = crate::ows::ows_vault_path(); diff --git a/src/bankr.rs b/src/bankr.rs new file mode 100644 index 0000000..83ae01c --- /dev/null +++ b/src/bankr.rs @@ -0,0 +1,694 @@ +//! Bankr Wallet API signer integration. +//! +//! Bankr is treated as an external signer source. The CLI resolves the EVM +//! wallet attached to a Bankr API key, asks Bankr to sign supported payloads, +//! and verifies the recovered signer address before accepting the signature. + +use std::env; +use std::time::Duration; + +use alloy::dyn_abi::TypedData; +use alloy_primitives::{Address as AlloyAddress, B256}; +use hypersdk::Address; +use hypersdk::hypercore::types::Signature as HyperliquidSignature; +use reqwest::StatusCode; +use serde::Deserialize; +use serde_json::Value; + +use crate::errors::{CliError, http_response_indicates_rate_limit}; +use crate::response_sanitization::labelled_untrusted_text; + +const DEFAULT_BANKR_API_BASE_URL: &str = "https://api.bankr.bot"; +const DEFAULT_SELECTOR: &str = "default"; +const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10); + +pub const BANKR_API_KEY_ENV: &str = "BANKR_API_KEY"; +pub const BANKR_API_BASE_URL_ENV: &str = "BANKR_API_BASE_URL"; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct BankrSigningConfig { + selector: String, + api_key: String, + api_base_url: String, + address: Address, +} + +impl BankrSigningConfig { + #[must_use] + pub fn new(selector: String, api_key: String, api_base_url: String, address: Address) -> Self { + Self { + selector, + api_key, + api_base_url, + address, + } + } + + #[must_use] + pub fn selector(&self) -> &str { + &self.selector + } + + #[must_use] + pub fn address(&self) -> Address { + self.address + } + + fn api_key(&self) -> &str { + &self.api_key + } + + fn api_base_url(&self) -> &str { + &self.api_base_url + } +} + +pub fn resolve_selector(selector: &str) -> Result { + let selector = selector.trim(); + if selector.is_empty() { + return Err(CliError::Configuration( + "--bankr-signer requires a non-empty selector".to_string(), + )); + } + if selector != DEFAULT_SELECTOR { + return Err(CliError::Unsupported(format!( + "bankr_unsupported_selector: only '{DEFAULT_SELECTOR}' is currently supported" + ))); + } + + let api_key = bankr_api_key()?; + let api_base_url = bankr_api_base_url(); + let address = wallet_address(&api_base_url, &api_key)?; + Ok(BankrSigningConfig::new( + selector.to_string(), + api_key, + api_base_url, + address, + )) +} + +pub fn unsupported_raw_l1_signing(selector: &str) -> CliError { + CliError::Unsupported(format!( + "Bankr signer '{selector}' cannot sign raw Hyperliquid L1 action hashes with the currently documented Bankr Wallet API; use OWS, a local signing account, keystore, or private key for this live action" + )) +} + +pub fn unsupported_local_private_key(selector: &str) -> CliError { + CliError::Unsupported(format!( + "Bankr signer '{selector}' does not expose a local private key; use a local signing account, keystore, or private key for this command" + )) +} + +pub fn sign_typed_data( + config: &BankrSigningConfig, + typed_data: &TypedData, +) -> Result { + let typed_data_value = bankr_typed_data_value(typed_data)?; + let response: SignResponse = post_json( + config.api_base_url(), + "/wallet/sign", + config.api_key(), + &serde_json::json!({ + "signatureType": "eth_signTypedData_v4", + "typedData": typed_data_value, + }), + "signing Bankr typed data", + )?; + let signature = hyperliquid_signature_from_bankr(response)?; + let alloy_signature: alloy_primitives::Signature = signature.into(); + let signing_hash = typed_data.eip712_signing_hash().map_err(|err| { + CliError::Internal(anyhow::anyhow!("failed to hash Bankr typed data: {err}")) + })?; + verify_recovered_address(config, &alloy_signature, signing_hash)?; + Ok(signature) +} + +pub fn sign_message( + config: &BankrSigningConfig, + message: &[u8], +) -> Result { + let message = std::str::from_utf8(message).map_err(|_| { + CliError::Unsupported( + "bankr_unsupported_message: Bankr personal_sign requires UTF-8 message bytes" + .to_string(), + ) + })?; + let response: SignResponse = post_json( + config.api_base_url(), + "/wallet/sign", + config.api_key(), + &serde_json::json!({ + "signatureType": "personal_sign", + "message": message, + }), + "signing Bankr message", + )?; + let signature = alloy_signature_from_bankr(response)?; + let recovered = signature + .recover_address_from_msg(message.as_bytes()) + .map_err(|err| { + CliError::InvalidAuth(format!( + "bankr_malformed_response: failed to recover Bankr message signer: {err}" + )) + })?; + verify_address_matches(config, recovered)?; + Ok(signature) +} + +fn wallet_address(api_base_url: &str, api_key: &str) -> Result { + let response: WalletMeResponse = get_json( + api_base_url, + "/wallet/me", + api_key, + "resolving Bankr wallet", + )?; + let address = response + .evm_address() + .ok_or_else(|| { + CliError::InvalidAuth( + "bankr_no_evm_wallet: Bankr wallet response did not include an EVM address" + .to_string(), + ) + })? + .parse::
() + .map_err(|_| { + CliError::InvalidAuth( + "bankr_malformed_response: Bankr returned an invalid EVM address".to_string(), + ) + })?; + Ok(address) +} + +fn get_json Deserialize<'de>>( + api_base_url: &str, + path: &str, + api_key: &str, + context: &'static str, +) -> Result { + let url = bankr_url(api_base_url, path)?; + let response = reqwest::blocking::Client::builder() + .timeout(DEFAULT_TIMEOUT) + .build() + .map_err(|err| CliError::Internal(anyhow::anyhow!(err)))? + .get(url) + .header("X-API-Key", api_key) + .send() + .map_err(|err| CliError::Unavailable(format!("Check your network connection. {err}")))?; + decode_response(response, context) +} + +fn post_json Deserialize<'de>>( + api_base_url: &str, + path: &str, + api_key: &str, + payload: &Value, + context: &'static str, +) -> Result { + let url = bankr_url(api_base_url, path)?; + let response = reqwest::blocking::Client::builder() + .timeout(DEFAULT_TIMEOUT) + .build() + .map_err(|err| CliError::Internal(anyhow::anyhow!(err)))? + .post(url) + .header("X-API-Key", api_key) + .json(payload) + .send() + .map_err(|err| CliError::Unavailable(format!("Check your network connection. {err}")))?; + decode_response(response, context) +} + +fn decode_response Deserialize<'de>>( + response: reqwest::blocking::Response, + context: &'static str, +) -> Result { + let status = response.status(); + let body = response + .text() + .map_err(|err| CliError::Unavailable(format!("Failed to read Bankr response. {err}")))?; + ensure_bankr_success(status, &body)?; + serde_json::from_str::(&body).map_err(|err| { + let body = labelled_untrusted_text(&body); + CliError::InvalidAuth(format!( + "bankr_malformed_response: decode failed while {context}: {err}; body={body}" + )) + }) +} + +fn ensure_bankr_success(status: StatusCode, body: &str) -> Result<(), CliError> { + if http_response_indicates_rate_limit(status.as_u16(), body) { + return Err(CliError::RateLimited); + } + if status == StatusCode::UNAUTHORIZED { + return Err(CliError::InvalidAuth(bankr_error_message( + "bankr_auth_required", + body, + ))); + } + if status == StatusCode::FORBIDDEN { + return Err(CliError::InvalidAuth(bankr_error_message( + "bankr_access_denied", + body, + ))); + } + if !status.is_success() { + return Err(CliError::Unavailable(format!( + "Bankr API returned HTTP {status}. Check your network connection." + ))); + } + Ok(()) +} + +fn bankr_error_message(prefix: &'static str, body: &str) -> String { + let body = labelled_untrusted_text(body); + format!("{prefix}: {body}") +} + +fn bankr_url(api_base_url: &str, path: &str) -> Result { + let mut url = reqwest::Url::parse(api_base_url) + .map_err(|err| CliError::Configuration(format!("invalid Bankr API base URL: {err}")))?; + url.set_path(path); + url.set_query(None); + Ok(url) +} + +fn bankr_api_key() -> Result { + env::var(BANKR_API_KEY_ENV) + .ok() + .filter(|value| !value.is_empty()) + .ok_or_else(|| { + CliError::InvalidAuth(format!( + "{BANKR_API_KEY_ENV} is required when using --bankr-signer" + )) + }) +} + +fn bankr_api_base_url() -> String { + env::var(BANKR_API_BASE_URL_ENV) + .ok() + .filter(|value| !value.is_empty()) + .unwrap_or_else(|| DEFAULT_BANKR_API_BASE_URL.to_string()) +} + +fn bankr_typed_data_value(typed_data: &TypedData) -> Result { + let mut value = serde_json::to_value(typed_data).map_err(|err| { + CliError::Internal(anyhow::anyhow!("failed to encode Bankr typed data: {err}")) + })?; + ensure_eip712_domain_type(&mut value); + pad_odd_hex_typed_values(&mut value); + Ok(value) +} + +fn ensure_eip712_domain_type(value: &mut Value) { + let Some(domain) = value.get("domain").and_then(Value::as_object).cloned() else { + return; + }; + let Some(types) = value.get_mut("types").and_then(Value::as_object_mut) else { + return; + }; + if types.contains_key("EIP712Domain") { + return; + } + + let mut fields = Vec::new(); + for (name, type_name) in [ + ("name", "string"), + ("version", "string"), + ("chainId", "uint256"), + ("verifyingContract", "address"), + ("salt", "bytes32"), + ] { + if domain.contains_key(name) { + fields.push(serde_json::json!({"name": name, "type": type_name})); + } + } + types.insert("EIP712Domain".to_string(), Value::Array(fields)); +} + +fn pad_odd_hex_typed_values(value: &mut Value) { + let Some(types) = value.get("types").and_then(Value::as_object).cloned() else { + return; + }; + if let Some(domain) = value.get_mut("domain") { + pad_struct_odd_hex_values("EIP712Domain", domain, &types); + } + let Some(primary_type) = value + .get("primaryType") + .and_then(Value::as_str) + .map(str::to_string) + else { + return; + }; + if let Some(message) = value.get_mut("message") { + pad_struct_odd_hex_values(&primary_type, message, &types); + } +} + +fn pad_struct_odd_hex_values( + type_name: &str, + value: &mut Value, + types: &serde_json::Map, +) { + let Some(fields) = types.get(type_name).and_then(Value::as_array).cloned() else { + return; + }; + let Some(object) = value.as_object_mut() else { + return; + }; + + for field in fields { + let Some(name) = field.get("name").and_then(Value::as_str) else { + continue; + }; + let Some(field_type) = field.get("type").and_then(Value::as_str) else { + continue; + }; + let Some(field_value) = object.get_mut(name) else { + continue; + }; + pad_field_odd_hex_values(field_type, field_value, types); + } +} + +fn pad_field_odd_hex_values( + field_type: &str, + value: &mut Value, + types: &serde_json::Map, +) { + if let Some(element_type) = field_type.strip_suffix("[]") { + if let Some(values) = value.as_array_mut() { + for value in values { + pad_field_odd_hex_values(element_type, value, types); + } + } + return; + } + + if types.contains_key(field_type) { + pad_struct_odd_hex_values(field_type, value, types); + return; + } + + if is_hex_encoded_eip712_scalar(field_type) + && let Some(text) = value.as_str() + && let Some(hex) = text.strip_prefix("0x") + && hex.len() % 2 == 1 + { + *value = Value::String(format!("0x0{hex}")); + } +} + +fn is_hex_encoded_eip712_scalar(field_type: &str) -> bool { + field_type == "bytes" + || field_type.starts_with("bytes") + || field_type.starts_with("uint") + || field_type.starts_with("int") +} + +fn hyperliquid_signature_from_bankr( + response: SignResponse, +) -> Result { + let signature = canonical_signature_hex(&response.signature)?; + signature.parse::().map_err(|err| { + CliError::InvalidAuth(format!( + "bankr_malformed_response: failed to parse Bankr signature: {err}" + )) + }) +} + +fn alloy_signature_from_bankr( + response: SignResponse, +) -> Result { + let signature = hyperliquid_signature_from_bankr(response)?; + Ok(signature.into()) +} + +fn canonical_signature_hex(signature: &str) -> Result { + let sig_hex = signature.strip_prefix("0x").unwrap_or(signature); + if sig_hex.len() != 130 { + return Err(CliError::InvalidAuth(format!( + "bankr_malformed_response: unexpected Bankr signature length {} hex chars; expected 130", + sig_hex.len() + ))); + } + let v = u8::from_str_radix(&sig_hex[128..130], 16).map_err(|err| { + CliError::InvalidAuth(format!( + "bankr_malformed_response: invalid Bankr recovery byte: {err}" + )) + })?; + let canonical_v = if v >= 27 { v } else { v + 27 }; + Ok(format!("0x{}{canonical_v:02x}", &sig_hex[..128])) +} + +fn verify_recovered_address( + config: &BankrSigningConfig, + signature: &alloy_primitives::Signature, + signing_hash: B256, +) -> Result<(), CliError> { + let recovered = signature + .recover_address_from_prehash(&signing_hash) + .map_err(|err| { + CliError::InvalidAuth(format!( + "bankr_malformed_response: failed to recover Bankr signer: {err}" + )) + })?; + verify_address_matches(config, recovered) +} + +fn verify_address_matches( + config: &BankrSigningConfig, + recovered: AlloyAddress, +) -> Result<(), CliError> { + let expected: AlloyAddress = config.address; + if recovered == expected { + return Ok(()); + } + + Err(CliError::InvalidAuth(format!( + "bankr_signer_mismatch: Bankr signature recovered {recovered}, expected {}", + config.address + ))) +} + +#[derive(Debug, Deserialize)] +struct WalletMeResponse { + #[serde(default, rename = "evmAddress")] + evm_address: Option, + #[serde(default)] + wallets: Vec, +} + +impl WalletMeResponse { + fn evm_address(&self) -> Option<&str> { + self.evm_address.as_deref().or_else(|| { + self.wallets + .iter() + .find(|wallet| wallet.chain.eq_ignore_ascii_case("evm")) + .map(|wallet| wallet.address.as_str()) + }) + } +} + +#[derive(Debug, Deserialize)] +struct BankrWalletAddress { + chain: String, + address: String, +} + +#[derive(Debug, Deserialize)] +struct SignResponse { + signature: String, +} + +#[cfg(test)] +mod tests { + use super::*; + + use alloy_v1::signers::SignerSync; + use hypersdk::hypercore::PrivateKeySigner; + use wiremock::matchers::{header, method, path}; + use wiremock::{Mock, MockServer, ResponseTemplate}; + + const KEY: &str = "0x0000000000000000000000000000000000000000000000000000000000000009"; + const API_KEY: &str = "bk_test_key"; + + fn test_typed_data() -> TypedData { + serde_json::from_value(serde_json::json!({ + "types": { + "EIP712Domain": [ + {"name": "name", "type": "string"}, + {"name": "chainId", "type": "uint256"} + ], + "TestAction": [ + {"name": "message", "type": "string"} + ] + }, + "primaryType": "TestAction", + "domain": {"name": "Hyperliquid", "chainId": "0x3e7"}, + "message": {"message": "hello bankr"} + })) + .unwrap() + } + + fn config(api_base_url: String) -> BankrSigningConfig { + let signer = KEY.parse::().unwrap(); + BankrSigningConfig::new( + "default".to_string(), + API_KEY.to_string(), + api_base_url, + signer.address(), + ) + } + + async fn run_blocking(f: impl FnOnce() -> T + Send + 'static) -> T { + tokio::task::spawn_blocking(f).await.unwrap() + } + + #[tokio::test(flavor = "multi_thread")] + async fn wallet_address_extracts_evm_wallet_from_bankr_response() { + let server = MockServer::start().await; + let signer = KEY.parse::().unwrap(); + Mock::given(method("GET")) + .and(path("/wallet/me")) + .and(header("X-API-Key", API_KEY)) + .respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({ + "success": true, + "wallets": [ + {"chain": "solana", "address": "5DcK"}, + {"chain": "evm", "address": signer.address().to_string()} + ] + }))) + .mount(&server) + .await; + + let server_uri = server.uri(); + let address = run_blocking(move || wallet_address(&server_uri, API_KEY).unwrap()).await; + + assert_eq!(address, signer.address()); + } + + #[tokio::test(flavor = "multi_thread")] + async fn sign_typed_data_verifies_recovered_bankr_address() { + let server = MockServer::start().await; + let typed_data = test_typed_data(); + let signer = KEY.parse::().unwrap(); + let signature = signer.sign_dynamic_typed_data_sync(&typed_data).unwrap(); + Mock::given(method("POST")) + .and(path("/wallet/sign")) + .and(header("X-API-Key", API_KEY)) + .respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({ + "success": true, + "signature": signature.to_string(), + "signer": signer.address().to_string(), + "signatureType": "eth_signTypedData_v4" + }))) + .mount(&server) + .await; + + let server_uri = server.uri(); + let typed_data_for_signing = typed_data.clone(); + let signature = run_blocking(move || { + sign_typed_data(&config(server_uri), &typed_data_for_signing).unwrap() + }) + .await; + let alloy_signature: alloy_primitives::Signature = signature.into(); + let recovered = alloy_signature + .recover_address_from_prehash(&typed_data.eip712_signing_hash().unwrap()) + .unwrap(); + + assert_eq!(recovered, signer.address()); + let requests = server.received_requests().await.unwrap(); + assert_eq!( + requests[0].body_json::().unwrap()["signatureType"], + "eth_signTypedData_v4" + ); + } + + #[tokio::test(flavor = "multi_thread")] + async fn sign_typed_data_rejects_signer_mismatch() { + let server = MockServer::start().await; + let typed_data = test_typed_data(); + let signer = KEY.parse::().unwrap(); + let other = "0x000000000000000000000000000000000000000000000000000000000000000a" + .parse::() + .unwrap(); + let signature = other.sign_dynamic_typed_data_sync(&typed_data).unwrap(); + Mock::given(method("POST")) + .and(path("/wallet/sign")) + .respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({ + "success": true, + "signature": signature.to_string() + }))) + .mount(&server) + .await; + + let server_uri = server.uri(); + let typed_data_for_signing = typed_data.clone(); + let err = run_blocking(move || { + sign_typed_data(&config(server_uri), &typed_data_for_signing).unwrap_err() + }) + .await; + + assert_eq!(err.exit_code(), 10); + assert!(err.to_string().contains("bankr_signer_mismatch")); + assert_ne!(signer.address(), other.address()); + } + + #[tokio::test(flavor = "multi_thread")] + async fn sign_message_verifies_recovered_bankr_address() { + let server = MockServer::start().await; + let signer = KEY.parse::().unwrap(); + let signature = signer.sign_message_sync(b"hello bankr").unwrap(); + Mock::given(method("POST")) + .and(path("/wallet/sign")) + .and(header("X-API-Key", API_KEY)) + .respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({ + "success": true, + "signature": signature.to_string(), + "signer": signer.address().to_string(), + "signatureType": "personal_sign" + }))) + .mount(&server) + .await; + + let server_uri = server.uri(); + let signature = + run_blocking(move || sign_message(&config(server_uri), b"hello bankr").unwrap()).await; + let recovered = signature.recover_address_from_msg(b"hello bankr").unwrap(); + + assert_eq!(recovered, signer.address()); + let requests = server.received_requests().await.unwrap(); + assert_eq!( + requests[0].body_json::().unwrap()["signatureType"], + "personal_sign" + ); + } + + #[tokio::test(flavor = "multi_thread")] + async fn sign_message_rejects_non_utf8_messages_before_request() { + let server = MockServer::start().await; + let err = sign_message(&config(server.uri()), &[0xff]).unwrap_err(); + + assert_eq!(err.exit_code(), 13); + assert!(err.to_string().contains("bankr_unsupported_message")); + assert!(server.received_requests().await.unwrap().is_empty()); + } + + #[tokio::test(flavor = "multi_thread")] + async fn bankr_forbidden_response_maps_to_auth_failure_without_leaking_key() { + let server = MockServer::start().await; + Mock::given(method("GET")) + .and(path("/wallet/me")) + .respond_with(ResponseTemplate::new(403).set_body_json(serde_json::json!({ + "error": "Read-only API key" + }))) + .mount(&server) + .await; + + let server_uri = server.uri(); + let err = run_blocking(move || wallet_address(&server_uri, API_KEY).unwrap_err()).await; + + assert_eq!(err.exit_code(), 10); + assert!(err.to_string().contains("bankr_access_denied")); + assert!(!err.to_string().contains(API_KEY)); + } +} diff --git a/src/cli_runtime.rs b/src/cli_runtime.rs index e64720f..bec9c1d 100644 --- a/src/cli_runtime.rs +++ b/src/cli_runtime.rs @@ -67,6 +67,7 @@ async fn run_command(cli: &Cli, registry_path: Option<&[String]>) -> Result<(), context.keystore_password.as_deref(), context.account.as_deref(), context.ows_signer.as_deref(), + context.bankr_signer.as_deref(), cli.format, ), Some(Commands::Wallet { @@ -77,6 +78,7 @@ async fn run_command(cli: &Cli, registry_path: Option<&[String]>) -> Result<(), context.keystore_password.as_deref(), context.account.as_deref(), context.ows_signer.as_deref(), + context.bankr_signer.as_deref(), cli.format, ), Some(Commands::Perps { @@ -1440,6 +1442,7 @@ struct AppContext { keystore_password: Option, account: Option, ows_signer: Option, + bankr_signer: Option, network: config::Network, api_base_url_override: Option, } @@ -1452,17 +1455,19 @@ impl AppContext { } else { config::Network::Mainnet }; - let private_key = if cli.account.is_some() || cli.ows_signer.is_some() { - None - } else { - config::resolve_private_key(cli.private_key.as_deref())? - }; + let private_key = + if cli.account.is_some() || cli.ows_signer.is_some() || cli.bankr_signer.is_some() { + None + } else { + config::resolve_private_key(cli.private_key.as_deref())? + }; Ok(Self { private_key, keystore: cli.keystore.clone(), keystore_password: cli.keystore_password.clone(), account: cli.account.clone(), ows_signer: cli.ows_signer.clone(), + bankr_signer: cli.bankr_signer.clone(), network, api_base_url_override: config::resolve_api_base_url_override_for_network(network)?, }) @@ -1500,6 +1505,7 @@ impl AppContext { keystore_password: self.keystore_password.as_deref(), account_selector: self.account.as_deref(), ows_selector: self.ows_signer.as_deref(), + bankr_selector: self.bankr_signer.as_deref(), default_fallback: DefaultSignerFallback::AllowStoredDefaultOrFirst, }) } diff --git a/src/command_catalog.json b/src/command_catalog.json index beaa4b2..0285374 100644 --- a/src/command_catalog.json +++ b/src/command_catalog.json @@ -14,7 +14,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid meta", @@ -28,7 +29,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid perps list", @@ -49,7 +51,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid perps get ", @@ -77,7 +80,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid spot list", @@ -91,7 +95,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid spot get ", @@ -113,7 +118,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid book ", @@ -148,7 +154,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid mids", @@ -176,7 +183,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid candles ", @@ -224,7 +232,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid spread ", @@ -246,7 +255,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid funding ", @@ -268,7 +278,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid asset decode ", @@ -291,7 +302,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid asset search ", @@ -320,7 +332,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid outcomes list", @@ -342,7 +355,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid outcomes get ", @@ -363,7 +377,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid builder max-fee", @@ -392,7 +407,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid builder approved", @@ -414,7 +430,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid builder approve", @@ -451,7 +468,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "prompt", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid account fills
", @@ -490,7 +508,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid account fees
", @@ -512,7 +531,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid account rate-limit
", @@ -534,7 +554,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid account orders
", @@ -556,7 +577,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid account portfolio
", @@ -578,7 +600,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid account subaccounts
", @@ -600,7 +623,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid account portfolio-history
", @@ -622,7 +646,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid account ledger
", @@ -655,7 +680,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid account funding
", @@ -688,7 +714,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid account twap-history
", @@ -710,7 +737,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid account twap-fills
", @@ -749,7 +777,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid account abstraction
", @@ -771,7 +800,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid account abstraction set", @@ -805,7 +835,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "prompt", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid subaccount list
", @@ -830,7 +861,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid subaccount create", @@ -851,7 +883,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid subaccount transfer", @@ -898,7 +931,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "prompt", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid subaccount spot-transfer", @@ -952,7 +986,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "prompt", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid account ls", @@ -966,7 +1001,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_applicable" + "ows_signer": "not_applicable", + "bankr_signer": "not_required" }, { "command": "hyperliquid account add ", @@ -1003,7 +1039,8 @@ "dry_run": "optional", "raw_payload": "unsupported", "confirmation": "prompt", - "ows_signer": "not_applicable" + "ows_signer": "not_applicable", + "bankr_signer": "not_required" }, { "command": "hyperliquid account set-default ", @@ -1024,7 +1061,8 @@ "dry_run": "optional", "raw_payload": "unsupported", "confirmation": "prompt", - "ows_signer": "not_applicable" + "ows_signer": "not_applicable", + "bankr_signer": "not_required" }, { "command": "hyperliquid account remove ", @@ -1053,7 +1091,8 @@ "dry_run": "optional", "raw_payload": "unsupported", "confirmation": "prompt", - "ows_signer": "not_applicable" + "ows_signer": "not_applicable", + "bankr_signer": "not_required" }, { "command": "hyperliquid api-wallet create", @@ -1091,7 +1130,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid api-wallet approve", @@ -1129,7 +1169,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid api-wallet list", @@ -1153,7 +1194,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid api-wallet revoke", @@ -1174,7 +1216,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid wallet create", @@ -1188,7 +1231,8 @@ "dry_run": "optional", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_applicable" + "ows_signer": "not_applicable", + "bankr_signer": "not_required" }, { "command": "hyperliquid wallet import ", @@ -1208,7 +1252,8 @@ "dry_run": "optional", "raw_payload": "unsupported", "confirmation": "prompt", - "ows_signer": "not_applicable" + "ows_signer": "not_applicable", + "bankr_signer": "not_required" }, { "command": "hyperliquid wallet show", @@ -1222,7 +1267,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "address_selector_supported" + "ows_signer": "address_selector_supported", + "bankr_signer": "not_required" }, { "command": "hyperliquid wallet address", @@ -1236,7 +1282,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "address_selector_supported" + "ows_signer": "address_selector_supported", + "bankr_signer": "not_required" }, { "command": "hyperliquid wallet reset", @@ -1259,7 +1306,8 @@ "dry_run": "optional", "raw_payload": "unsupported", "confirmation": "prompt", - "ows_signer": "not_applicable" + "ows_signer": "not_applicable", + "bankr_signer": "not_required" }, { "command": "hyperliquid wallet import-mnemonic ", @@ -1284,7 +1332,8 @@ "dry_run": "optional", "raw_payload": "unsupported", "confirmation": "prompt", - "ows_signer": "not_applicable" + "ows_signer": "not_applicable", + "bankr_signer": "not_required" }, { "command": "hyperliquid wallet list", @@ -1298,7 +1347,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_applicable" + "ows_signer": "not_applicable", + "bankr_signer": "not_required" }, { "command": "hyperliquid wallet rename ", @@ -1325,7 +1375,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_applicable" + "ows_signer": "not_applicable", + "bankr_signer": "not_required" }, { "command": "hyperliquid wallet delete ", @@ -1354,7 +1405,8 @@ "dry_run": "optional", "raw_payload": "unsupported", "confirmation": "prompt", - "ows_signer": "not_applicable" + "ows_signer": "not_applicable", + "bankr_signer": "not_required" }, { "command": "hyperliquid wallet export ", @@ -1383,7 +1435,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "prompt", - "ows_signer": "not_applicable" + "ows_signer": "not_applicable", + "bankr_signer": "not_required" }, { "command": "hyperliquid orders open", @@ -1411,7 +1464,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid orders history", @@ -1425,7 +1479,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid orders status", @@ -1468,7 +1523,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid positions list", @@ -1496,7 +1552,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid staking validators", @@ -1510,7 +1567,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid staking summary
", @@ -1532,7 +1590,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid staking rewards
", @@ -1554,7 +1613,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid staking history
", @@ -1576,7 +1636,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid vault list", @@ -1633,7 +1694,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid vault search ", @@ -1679,7 +1741,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid vault get
", @@ -1701,7 +1764,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid vault positions
", @@ -1723,7 +1787,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid borrowlend rates", @@ -1737,7 +1802,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid borrowlend get ", @@ -1759,7 +1825,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid borrowlend user
", @@ -1781,7 +1848,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid borrowlend supply --amount ", @@ -1810,7 +1878,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid borrowlend withdraw --amount ", @@ -1843,7 +1912,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid prio status", @@ -1857,7 +1927,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid referral status", @@ -1871,7 +1942,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid orders create", @@ -2032,7 +2104,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "prompt", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid orders scale", @@ -2137,7 +2210,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "prompt", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid orders batch-create", @@ -2173,7 +2247,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "prompt", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid orders tpsl", @@ -2260,7 +2335,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "prompt", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid orders cancel ", @@ -2293,7 +2369,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid orders cancel-all", @@ -2334,7 +2411,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "prompt", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid orders modify ", @@ -2394,7 +2472,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid orders twap-create", @@ -2470,7 +2549,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "prompt", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid orders twap-cancel ", @@ -2512,7 +2592,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid positions update-leverage", @@ -2548,7 +2629,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid positions update-margin", @@ -2577,7 +2659,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid orders schedule-cancel", @@ -2620,7 +2703,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "prompt", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid transfer spot-to-perp", @@ -2650,7 +2734,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "prompt", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid transfer perp-to-spot", @@ -2680,7 +2765,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "prompt", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid transfer send", @@ -2720,7 +2806,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "prompt", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid transfer spot-send", @@ -2764,7 +2851,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "prompt", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid transfer send-asset", @@ -2827,7 +2915,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "prompt", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid transfer withdraw", @@ -2864,7 +2953,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "prompt", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid staking delegate", @@ -2893,7 +2983,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid staking undelegate", @@ -2922,7 +3013,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid staking deposit", @@ -2944,7 +3036,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid staking withdraw", @@ -2966,7 +3059,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid staking claim-rewards", @@ -2980,7 +3074,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid staking link initiate", @@ -3010,7 +3105,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "prompt", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid staking link finalize", @@ -3040,7 +3136,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "prompt", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid vault deposit", @@ -3069,7 +3166,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid vault withdraw", @@ -3098,7 +3196,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid prio bid", @@ -3132,7 +3231,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "none", - "ows_signer": "local_only" + "ows_signer": "local_only", + "bankr_signer": "not_required" }, { "command": "hyperliquid referral set ", @@ -3152,7 +3252,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid referral register ", @@ -3173,7 +3274,8 @@ "dry_run": "optional", "raw_payload": "dry_run_only", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid subscribe trades", @@ -3206,7 +3308,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid subscribe orderbook", @@ -3239,7 +3342,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid subscribe candles", @@ -3278,7 +3382,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid subscribe all-mids", @@ -3305,7 +3410,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid subscribe order-updates", @@ -3332,7 +3438,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid subscribe fills", @@ -3359,7 +3466,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "experimental_feature_gated" + "ows_signer": "experimental_feature_gated", + "bankr_signer": "not_required" }, { "command": "hyperliquid feedback", @@ -3413,7 +3521,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid schema", @@ -3434,7 +3543,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid update", @@ -3448,7 +3558,8 @@ "dry_run": "optional", "raw_payload": "unsupported", "confirmation": "none", - "ows_signer": "not_required" + "ows_signer": "not_required", + "bankr_signer": "not_required" }, { "command": "hyperliquid setup", @@ -3485,7 +3596,8 @@ "dry_run": "not_supported", "raw_payload": "unsupported", "confirmation": "prompt", - "ows_signer": "not_applicable" + "ows_signer": "not_applicable", + "bankr_signer": "not_required" } ] } diff --git a/src/command_metadata.rs b/src/command_metadata.rs index 6283844..08c1d7a 100644 --- a/src/command_metadata.rs +++ b/src/command_metadata.rs @@ -8,6 +8,7 @@ pub(crate) trait CatalogCommandMetadata { fn raw_payload(&self) -> Option<&str>; fn confirmation(&self) -> Option<&str>; fn ows_signer(&self) -> Option<&str>; + fn bankr_signer(&self) -> Option<&str>; fn auth_required(&self) -> bool; fn dangerous(&self) -> bool; } @@ -30,6 +31,7 @@ pub(crate) struct CommandMetadata { pub(crate) raw_payload: String, pub(crate) confirmation: String, pub(crate) ows_signer: String, + pub(crate) bankr_signer: String, } pub(crate) fn command_metadata( @@ -66,6 +68,10 @@ pub(crate) fn command_metadata( .ows_signer() .map(str::to_string) .unwrap_or_else(|| inferred_ows_signer(command_key, command)), + bankr_signer: command + .bankr_signer() + .map(str::to_string) + .unwrap_or_else(|| inferred_bankr_signer(command_key, command)), } } @@ -177,6 +183,22 @@ fn inferred_ows_signer(command_key: &str, command: &impl CatalogCommandMetadata) "not_required".to_string() } +fn inferred_bankr_signer(command_key: &str, command: &impl CatalogCommandMetadata) -> String { + if matches!(command_key, "wallet show" | "wallet address") { + return "address_selector_supported".to_string(); + } + if command_key == "prio bid" { + return "local_only".to_string(); + } + if is_local_only_command(command_key) { + return "not_applicable".to_string(); + } + if command.auth_required() { + return "unsupported_raw_l1_signing".to_string(); + } + "not_required".to_string() +} + fn is_local_only_command(command_key: &str) -> bool { is_interactive_local_command(command_key) || is_local_state_command(command_key) diff --git a/src/command_registry.rs b/src/command_registry.rs index 30050ae..fd3765f 100644 --- a/src/command_registry.rs +++ b/src/command_registry.rs @@ -70,6 +70,7 @@ pub struct CommandContract { pub confirmation: ConfirmationPolicy, pub transport: Vec, pub ows_signer: OwsSupport, + pub bankr_signer: BankrSupport, pub output_contract: OutputContract, pub handler: HandlerBinding, pub one_of_required: Vec>, @@ -92,6 +93,7 @@ impl CommandContract { let raw_payload = RawPayloadPolicy::from(metadata.raw_payload.as_str()); let confirmation = ConfirmationPolicy::from(metadata.confirmation.as_str()); let ows_signer = OwsSupport::from(metadata.ows_signer.as_str()); + let bankr_signer = BankrSupport::from(metadata.bankr_signer.as_str()); let transport = primary_transport(lifecycle); Ok(Self { command: command.command, @@ -109,6 +111,7 @@ impl CommandContract { confirmation, transport, ows_signer, + bankr_signer, output_contract: output_contract(&command_key, lifecycle, dry_run), handler: HandlerBinding::for_command_key(&command_key), one_of_required: command.one_of_required, @@ -157,6 +160,7 @@ impl CommandContract { "arg": if yes_support { Some("yes") } else { None }, }, "ows_signer": self.ows_signer, + "bankr_signer": self.bankr_signer, "transport": self.transport, "output_contract": self.output_contract, "stream_bounds": stream_bounds, @@ -266,6 +270,17 @@ pub enum OwsSupport { NotApplicable, } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)] +#[serde(rename_all = "snake_case")] +pub enum BankrSupport { + NotRequired, + AddressSelectorSupported, + TypedDataSupported, + UnsupportedRawL1Signing, + LocalOnly, + NotApplicable, +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)] #[serde(rename_all = "snake_case")] pub enum OutputContract { @@ -397,6 +412,19 @@ impl From<&str> for OwsSupport { } } +impl From<&str> for BankrSupport { + fn from(value: &str) -> Self { + match value { + "address_selector_supported" => Self::AddressSelectorSupported, + "typed_data_supported" => Self::TypedDataSupported, + "unsupported_raw_l1_signing" => Self::UnsupportedRawL1Signing, + "local_only" => Self::LocalOnly, + "not_applicable" => Self::NotApplicable, + _ => Self::NotRequired, + } + } +} + impl From<&str> for InputKind { fn from(value: &str) -> Self { match value { @@ -488,6 +516,8 @@ struct CatalogCommand { confirmation: Option, #[serde(default)] ows_signer: Option, + #[serde(default)] + bankr_signer: Option, description: String, #[serde(default)] one_of_required: Vec>, @@ -553,6 +583,10 @@ impl CatalogCommandMetadata for CatalogCommand { self.ows_signer.as_deref() } + fn bankr_signer(&self) -> Option<&str> { + self.bankr_signer.as_deref() + } + fn auth_required(&self) -> bool { self.auth_required } diff --git a/src/commands/schema.rs b/src/commands/schema.rs index 1b4e785..6c529e0 100644 --- a/src/commands/schema.rs +++ b/src/commands/schema.rs @@ -39,6 +39,7 @@ struct CommandSchema { confirmation: String, confirmation_bypass: Value, ows_signer: String, + bankr_signer: String, transport: Value, output_contract: String, stream_bounds: Value, @@ -172,6 +173,7 @@ fn command_schema(command: &CommandContract) -> CommandSchema { .cloned() .unwrap_or_else(|| json!({"supported": false, "arg": null})), ows_signer: metadata_string(&metadata, "ows_signer"), + bankr_signer: metadata_string(&metadata, "bankr_signer"), transport: metadata .get("transport") .cloned() diff --git a/src/commands/wallet.rs b/src/commands/wallet.rs index 91bb529..062fb01 100644 --- a/src/commands/wallet.rs +++ b/src/commands/wallet.rs @@ -406,8 +406,23 @@ pub fn show( keystore_password: Option<&str>, account_selector: Option<&str>, ows_selector: Option<&str>, + bankr_selector: Option<&str>, format: OutputFormat, ) -> Result<(), anyhow::Error> { + if let Some(selector) = bankr_selector { + let resolved = auth::resolve_bankr_signer(selector)?; + let (alias, source) = signer_display(resolved.source()); + print_wallet_info( + "Current wallet", + &resolved.address().to_string(), + alias, + &source, + None, + format, + ); + return Ok(()); + } + // When --ows-signer is explicit, resolve the specific wallet. // When no signer at all is specified, auto-detect the first OWS wallet. let vault_path = crate::ows::ows_vault_path(); @@ -511,6 +526,7 @@ fn signer_display(source: &SignerSource) -> (Option, String) { (Some(alias.clone()), "stored signing account".to_string()) } SignerSource::Ows { selector } => (None, format!("OWS signer ({selector})")), + SignerSource::Bankr { selector } => (None, format!("Bankr signer ({selector})")), } } @@ -520,11 +536,14 @@ pub fn address( keystore_password: Option<&str>, account_selector: Option<&str>, ows_selector: Option<&str>, + bankr_selector: Option<&str>, format: OutputFormat, ) -> Result<(), anyhow::Error> { let vault_path = crate::ows::ows_vault_path(); - let address_str = if let Some(selector) = ows_selector { + let address_str = if let Some(selector) = bankr_selector { + auth::resolve_bankr_signer(selector)?.address().to_string() + } else if let Some(selector) = ows_selector { // Explicit --ows-signer: resolve the specific wallet match crate::ows::get_ows_wallet(selector, vault_path.as_deref()) { Ok(wallet) => { diff --git a/src/lib.rs b/src/lib.rs index 47e40ae..afe1841 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,7 @@ extern crate alloy_signer_local_v1 as _; pub mod auth; +pub mod bankr; pub mod command_context; pub mod command_handlers; pub(crate) mod command_metadata; diff --git a/src/main.rs b/src/main.rs index 17ae703..2ad7327 100644 --- a/src/main.rs +++ b/src/main.rs @@ -65,7 +65,7 @@ struct Cli { #[arg( long, global = true, - conflicts_with_all = ["private_key", "keystore", "keystore_password", "ows_signer"] + conflicts_with_all = ["private_key", "keystore", "keystore_password", "ows_signer", "bankr_signer"] )] account: Option, @@ -75,10 +75,19 @@ struct Cli { global = true, value_name = "SELECTOR", alias = "wallet", - conflicts_with_all = ["private_key", "keystore", "keystore_password", "account"] + conflicts_with_all = ["private_key", "keystore", "keystore_password", "account", "bankr_signer"] )] ows_signer: Option, + /// Bankr signer selector. Currently only 'default' is supported and uses BANKR_API_KEY. + #[arg( + long, + global = true, + value_name = "SELECTOR", + conflicts_with_all = ["private_key", "keystore", "keystore_password", "account", "ows_signer"] + )] + bankr_signer: Option, + /// Use testnet instead of mainnet #[arg(long, global = true)] testnet: bool, diff --git a/src/resolvers.rs b/src/resolvers.rs index d131169..4695903 100644 --- a/src/resolvers.rs +++ b/src/resolvers.rs @@ -27,6 +27,7 @@ pub struct SignerResolverInput<'a> { pub keystore_password: Option<&'a str>, pub account_selector: Option<&'a str>, pub ows_selector: Option<&'a str>, + pub bankr_selector: Option<&'a str>, pub default_fallback: DefaultSignerFallback, } @@ -37,6 +38,10 @@ pub fn resolve_selected_signer( return auth::resolve_signer_with_account_and_ows(None, None, None, None, Some(selector)); } + if let Some(selector) = input.bankr_selector { + return auth::resolve_bankr_signer(selector); + } + if let Some(private_key) = input.resolved_private_key { return auth::resolve_signer_with_account_and_ows( Some(private_key), @@ -276,6 +281,7 @@ mod tests { keystore_password: None, account_selector: None, ows_selector: Some("0x0000000000000000000000000000000000000001"), + bankr_selector: None, default_fallback: DefaultSignerFallback::Disallow, }) .unwrap(); diff --git a/src/signing.rs b/src/signing.rs index fecbfc2..b3cc031 100644 --- a/src/signing.rs +++ b/src/signing.rs @@ -25,12 +25,14 @@ pub enum SignerSource { Keystore, StoredAccount { alias: String }, Ows { selector: String }, + Bankr { selector: String }, } #[derive(Debug, Clone)] enum SignerBackend { LocalPrivateKey(PrivateKeySigner), Ows(crate::ows::OwsSigningConfig), + Bankr(crate::bankr::BankrSigningConfig), } #[derive(Debug, Clone)] @@ -70,11 +72,23 @@ impl SelectedSigner { } } + #[must_use] + pub fn bankr(config: crate::bankr::BankrSigningConfig) -> Self { + let selector = config.selector().to_string(); + let address = config.address(); + Self { + backend: SignerBackend::Bankr(config), + source: SignerSource::Bankr { selector }, + query_address: address, + } + } + #[must_use] pub fn address(&self) -> Address { match &self.backend { SignerBackend::LocalPrivateKey(signer) => signer.address(), SignerBackend::Ows(config) => config.address(), + SignerBackend::Bankr(config) => config.address(), } } @@ -94,6 +108,9 @@ impl SelectedSigner { SignerBackend::Ows(config) => { Err(crate::ows::unsupported_live_signing(config.selector())) } + SignerBackend::Bankr(config) => Err(crate::bankr::unsupported_local_private_key( + config.selector(), + )), } } @@ -108,6 +125,7 @@ impl SelectedSigner { SignerBackend::Ows(config) => { Err(crate::ows::unsupported_live_signing(config.selector())) } + SignerBackend::Bankr(_) => Ok(()), } } @@ -148,6 +166,10 @@ impl SelectedSigner { CliError::Internal(anyhow::anyhow!("failed to encode signed action: {err}")) }) } + SignerBackend::Bankr(config) => { + let _ = (action, nonce, vault_address, chain); + Err(crate::bankr::unsupported_raw_l1_signing(config.selector())) + } } } @@ -158,6 +180,7 @@ impl SelectedSigner { .map(Into::into) .map_err(|err| CliError::Internal(anyhow::anyhow!("failed to sign action: {err}"))), SignerBackend::Ows(config) => crate::ows::sign_typed_data(config, typed_data), + SignerBackend::Bankr(config) => crate::bankr::sign_typed_data(config, typed_data), } } @@ -173,6 +196,10 @@ impl SelectedSigner { SignerBackend::Ows(config) => { crate::ows::sign_hash(config, agent_signing_hash(chain, connection_id)) } + SignerBackend::Bankr(config) => { + let _ = (chain, connection_id); + Err(crate::bankr::unsupported_raw_l1_signing(config.selector())) + } } } @@ -184,6 +211,7 @@ impl SelectedSigner { }) } SignerBackend::Ows(config) => crate::ows::sign_message(config, message), + SignerBackend::Bankr(config) => crate::bankr::sign_message(config, message), } } } @@ -279,4 +307,36 @@ mod tests { ); assert_eq!(selected.sign_message(b"nope").unwrap_err().exit_code(), 13); } + + #[test] + fn bankr_signer_rejects_raw_l1_action_signing() { + let address: Address = "0x0000000000000000000000000000000000000001" + .parse() + .unwrap(); + let selected = SelectedSigner::bankr(crate::bankr::BankrSigningConfig::new( + "default".to_string(), + "bk_test_key".to_string(), + "https://api.bankr.bot".to_string(), + address, + )); + + let err = selected + .sign_l1_action_sync( + Action::UpdateLeverage(hypersdk::hypercore::api::UpdateLeverage { + asset: 3, + is_cross: true, + leverage: 2, + }), + 1_777_963_000_000, + None, + Chain::Testnet, + ) + .unwrap_err(); + + assert_eq!(err.exit_code(), 13); + assert!( + err.to_string() + .contains("cannot sign raw Hyperliquid L1 action hashes") + ); + } } diff --git a/tests/fixtures/contracts/registry_inventory.json b/tests/fixtures/contracts/registry_inventory.json index 78d3771..d3044a0 100644 --- a/tests/fixtures/contracts/registry_inventory.json +++ b/tests/fixtures/contracts/registry_inventory.json @@ -38,7 +38,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -77,7 +78,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -131,7 +133,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -198,7 +201,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -238,7 +242,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -292,7 +297,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -371,7 +377,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -437,7 +444,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -542,7 +550,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -595,7 +604,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -648,7 +658,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -702,7 +713,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -769,7 +781,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -823,7 +836,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -877,7 +891,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -944,7 +959,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -998,7 +1014,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -1078,7 +1095,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -1171,7 +1189,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -1225,7 +1244,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -1279,7 +1299,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -1333,7 +1354,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -1387,7 +1409,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -1441,7 +1464,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -1495,7 +1519,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -1575,7 +1600,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -1655,7 +1681,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -1709,7 +1736,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -1802,7 +1830,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -1856,7 +1885,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -1928,7 +1958,8 @@ "risk": "account_state", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [ @@ -1984,7 +2015,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [ @@ -2040,7 +2072,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [ @@ -2138,7 +2171,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [ @@ -2249,7 +2283,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -2289,7 +2324,8 @@ "risk": "local_state", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -2382,7 +2418,8 @@ "risk": "local_secret", "transport": [ "cli_interactive" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -2436,7 +2473,8 @@ "risk": "local_state", "transport": [ "cli_interactive" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -2503,7 +2541,8 @@ "risk": "local_state", "transport": [ "cli_interactive" - ] + ], + "bankr_signer": null }, { "aliases": [ @@ -2598,7 +2637,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [ @@ -2693,7 +2733,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [ @@ -2749,7 +2790,8 @@ "risk": "account_state", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [ @@ -2805,7 +2847,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -2845,7 +2888,8 @@ "risk": "local_secret", "transport": [ "cli_interactive" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -2899,7 +2943,8 @@ "risk": "local_secret", "transport": [ "cli_interactive" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -2939,7 +2984,8 @@ "risk": "local_secret", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -2979,7 +3025,8 @@ "risk": "local_secret", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -3033,7 +3080,8 @@ "risk": "local_state", "transport": [ "cli_interactive" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -3100,7 +3148,8 @@ "risk": "local_secret", "transport": [ "cli_interactive" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -3140,7 +3189,8 @@ "risk": "local_state", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -3207,7 +3257,8 @@ "risk": "local_state", "transport": [ "cli_interactive" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -3274,7 +3325,8 @@ "risk": "local_state", "transport": [ "cli_interactive" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -3341,7 +3393,8 @@ "risk": "local_secret", "transport": [ "cli_interactive" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -3408,7 +3461,8 @@ "risk": "account_state", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -3448,7 +3502,8 @@ "risk": "account_state", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -3535,7 +3590,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -3602,7 +3658,8 @@ "risk": "account_state", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -3642,7 +3699,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -3696,7 +3754,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -3750,7 +3809,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -3804,7 +3864,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [ @@ -3911,7 +3972,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [ @@ -4011,7 +4073,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [ @@ -4067,7 +4130,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [ @@ -4123,7 +4187,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -4163,7 +4228,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -4217,7 +4283,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -4271,7 +4338,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -4338,7 +4406,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -4418,7 +4487,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -4458,7 +4528,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -4498,7 +4569,8 @@ "risk": "account_state", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -4818,7 +4890,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -5025,7 +5098,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -5105,7 +5179,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -5284,7 +5359,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -5364,7 +5440,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -5457,7 +5534,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -5583,7 +5661,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -5734,7 +5813,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -5827,7 +5907,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -5907,7 +5988,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -5974,7 +6056,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -6067,7 +6150,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [ @@ -6136,7 +6220,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [ @@ -6205,7 +6290,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [ @@ -6287,7 +6373,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [ @@ -6382,7 +6469,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [ @@ -6516,7 +6604,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [ @@ -6598,7 +6687,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -6665,7 +6755,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -6732,7 +6823,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -6786,7 +6878,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -6840,7 +6933,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -6880,7 +6974,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -6948,7 +7043,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -7016,7 +7112,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [ @@ -7085,7 +7182,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [ @@ -7154,7 +7252,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -7234,7 +7333,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -7288,7 +7388,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -7342,7 +7443,8 @@ "risk": "funds_movement", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -7422,7 +7524,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -7502,7 +7605,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -7595,7 +7699,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -7662,7 +7767,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -7729,7 +7835,8 @@ "risk": "account_state", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -7796,7 +7903,8 @@ "risk": "account_state", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -7908,7 +8016,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -7961,7 +8070,8 @@ "risk": "none", "transport": [ "cli_process" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -8000,7 +8110,8 @@ "risk": "local_state", "transport": [ "cli_interactive" - ] + ], + "bankr_signer": null }, { "aliases": [], @@ -8079,7 +8190,8 @@ "risk": "local_secret", "transport": [ "cli_interactive" - ] + ], + "bankr_signer": null } ], "review_required_to_update": true diff --git a/tests/fixtures/contracts/schema_high_risk_metadata.json b/tests/fixtures/contracts/schema_high_risk_metadata.json index f7b0c01..f1e762a 100644 --- a/tests/fixtures/contracts/schema_high_risk_metadata.json +++ b/tests/fixtures/contracts/schema_high_risk_metadata.json @@ -10,7 +10,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -21,7 +22,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "account_state" + "risk": "account_state", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -32,7 +34,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -43,7 +46,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -54,7 +58,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": false, @@ -65,7 +70,8 @@ "lifecycle": "read_only", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_state" + "risk": "local_state", + "bankr_signer": "not_required" }, { "auth_required": false, @@ -76,7 +82,8 @@ "lifecycle": "interactive_local", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_secret" + "risk": "local_secret", + "bankr_signer": "not_required" }, { "auth_required": false, @@ -87,7 +94,8 @@ "lifecycle": "interactive_local", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_state" + "risk": "local_state", + "bankr_signer": "not_required" }, { "auth_required": false, @@ -98,7 +106,8 @@ "lifecycle": "interactive_local", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_state" + "risk": "local_state", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -109,7 +118,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -120,7 +130,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -131,7 +142,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": false, @@ -142,7 +154,8 @@ "lifecycle": "interactive_local", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_secret" + "risk": "local_secret", + "bankr_signer": "not_required" }, { "auth_required": false, @@ -153,7 +166,8 @@ "lifecycle": "interactive_local", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_secret" + "risk": "local_secret", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -164,7 +178,8 @@ "lifecycle": "read_only", "ows_signer": "address_selector_supported", "raw_payload": "unsupported", - "risk": "local_secret" + "risk": "local_secret", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -175,7 +190,8 @@ "lifecycle": "read_only", "ows_signer": "address_selector_supported", "raw_payload": "unsupported", - "risk": "local_secret" + "risk": "local_secret", + "bankr_signer": "not_required" }, { "auth_required": false, @@ -186,7 +202,8 @@ "lifecycle": "interactive_local", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_state" + "risk": "local_state", + "bankr_signer": "not_required" }, { "auth_required": false, @@ -197,7 +214,8 @@ "lifecycle": "interactive_local", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_secret" + "risk": "local_secret", + "bankr_signer": "not_required" }, { "auth_required": false, @@ -208,7 +226,8 @@ "lifecycle": "read_only", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_state" + "risk": "local_state", + "bankr_signer": "not_required" }, { "auth_required": false, @@ -219,7 +238,8 @@ "lifecycle": "interactive_local", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_state" + "risk": "local_state", + "bankr_signer": "not_required" }, { "auth_required": false, @@ -230,7 +250,8 @@ "lifecycle": "interactive_local", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_state" + "risk": "local_state", + "bankr_signer": "not_required" }, { "auth_required": false, @@ -241,7 +262,8 @@ "lifecycle": "interactive_local", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_secret" + "risk": "local_secret", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -252,7 +274,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -263,7 +286,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -274,7 +298,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -285,7 +310,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -296,7 +322,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -307,7 +334,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -318,7 +346,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -329,7 +358,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -340,7 +370,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -351,7 +382,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -362,7 +394,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -373,7 +406,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -384,7 +418,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -395,7 +430,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -406,7 +442,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -417,7 +454,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -428,7 +466,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -439,7 +478,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -450,7 +490,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -461,7 +502,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -472,7 +514,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -483,7 +526,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -494,7 +538,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -505,7 +550,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -516,7 +562,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -527,7 +574,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -538,7 +586,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -549,7 +598,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -560,7 +610,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -571,7 +622,8 @@ "lifecycle": "live_mutating", "ows_signer": "local_only", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -582,7 +634,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": true, @@ -593,7 +646,8 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement" + "risk": "funds_movement", + "bankr_signer": "not_required" }, { "auth_required": false, @@ -604,7 +658,8 @@ "lifecycle": "interactive_local", "ows_signer": "not_required", "raw_payload": "unsupported", - "risk": "local_state" + "risk": "local_state", + "bankr_signer": "not_required" }, { "auth_required": false, @@ -615,7 +670,8 @@ "lifecycle": "interactive_local", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_secret" + "risk": "local_secret", + "bankr_signer": "not_required" } ], "review_required_to_update": true diff --git a/tests/fixtures/contracts/schema_representative.json b/tests/fixtures/contracts/schema_representative.json index 2812de3..08a85c4 100644 --- a/tests/fixtures/contracts/schema_representative.json +++ b/tests/fixtures/contracts/schema_representative.json @@ -445,7 +445,8 @@ "stream_bounds": null, "transport": [ "cli_process" - ] + ], + "bankr_signer": "not_required" } }, "lifecycle": "live_mutating", @@ -457,7 +458,8 @@ "stream_bounds": null, "transport": [ "cli_process" - ] + ], + "bankr_signer": "not_required" }, { "aliases": [], @@ -620,7 +622,8 @@ "stream_bounds": null, "transport": [ "cli_process" - ] + ], + "bankr_signer": "not_required" } }, "lifecycle": "live_mutating", @@ -632,7 +635,8 @@ "stream_bounds": null, "transport": [ "cli_process" - ] + ], + "bankr_signer": "not_required" }, { "aliases": [ @@ -737,7 +741,8 @@ "stream_bounds": null, "transport": [ "cli_process" - ] + ], + "bankr_signer": "not_required" } }, "lifecycle": "live_mutating", @@ -749,7 +754,8 @@ "stream_bounds": null, "transport": [ "cli_process" - ] + ], + "bankr_signer": "not_required" }, { "aliases": [], @@ -790,7 +796,8 @@ "stream_bounds": null, "transport": [ "cli_process" - ] + ], + "bankr_signer": "not_required" } }, "lifecycle": "read_only", @@ -802,7 +809,8 @@ "stream_bounds": null, "transport": [ "cli_process" - ] + ], + "bankr_signer": "not_required" }, { "aliases": [], @@ -885,7 +893,8 @@ "stream_bounds": null, "transport": [ "cli_process" - ] + ], + "bankr_signer": "not_required" } }, "lifecycle": "live_mutating", @@ -897,7 +906,8 @@ "stream_bounds": null, "transport": [ "cli_process" - ] + ], + "bankr_signer": "not_required" }, { "aliases": [], @@ -984,7 +994,8 @@ }, "transport": [ "cli_process" - ] + ], + "bankr_signer": "not_required" } }, "lifecycle": "streaming", @@ -1006,7 +1017,8 @@ }, "transport": [ "cli_process" - ] + ], + "bankr_signer": "not_required" } ], "review_required_to_update": true diff --git a/tests/registry_contracts.rs b/tests/registry_contracts.rs index 38f6660..ff0158b 100644 --- a/tests/registry_contracts.rs +++ b/tests/registry_contracts.rs @@ -71,6 +71,10 @@ fn registry_inventory_matches_schema_contracts() { command_value["ows_signer"], schema["json_schema"]["x-hyperliquid"]["ows_signer"], "registry/schema drift for {command_key} field ows_signer" ); + assert_eq!( + command_value["bankr_signer"], schema["json_schema"]["x-hyperliquid"]["bankr_signer"], + "registry/schema drift for {command_key} field bankr_signer" + ); assert_one_of_required_matches_schema( &command_key, &command_value["one_of_required"], diff --git a/tests/release_artifacts.rs b/tests/release_artifacts.rs index 4c0ac26..be5acc8 100644 --- a/tests/release_artifacts.rs +++ b/tests/release_artifacts.rs @@ -525,6 +525,7 @@ fn tool_catalog_materializes_registry_policy_metadata() { "raw_payload", "confirmation", "ows_signer", + "bankr_signer", ] { assert_eq!( catalog_command[field], registry_value[field], diff --git a/tests/schema_contracts.rs b/tests/schema_contracts.rs index 52ccf2b..e0a8562 100644 --- a/tests/schema_contracts.rs +++ b/tests/schema_contracts.rs @@ -42,6 +42,7 @@ fn high_risk_schema_metadata_stays_classified() { "raw_payload": schema["raw_payload"], "confirmation": schema["confirmation"], "ows_signer": schema["json_schema"]["x-hyperliquid"]["ows_signer"], + "bankr_signer": schema["json_schema"]["x-hyperliquid"]["bankr_signer"], }) }) .collect::>(); From fedb0030ba79cc95fdf4b617cbf369b1dfba5290 Mon Sep 17 00:00:00 2001 From: Sayo <82053242+wtfsayo@users.noreply.github.com> Date: Thu, 21 May 2026 00:38:30 +0530 Subject: [PATCH 2/3] Fix Bankr HTTP integration for async CLI and API payload shape. Use async reqwest with block_in_place so --bankr-signer works inside the Tokio runtime, normalize EIP-712 integers for Bankr validation, and surface sign/400 failures with clearer auth errors until live signing is unblocked. Co-authored-by: Cursor --- Cargo.lock | 1 - Cargo.toml | 2 +- src/bankr.rs | 221 ++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 200 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 99f4c13..a018e54 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5289,7 +5289,6 @@ dependencies = [ "base64 0.22.1", "bytes", "encoding_rs", - "futures-channel", "futures-core", "futures-util", "h2", diff --git a/Cargo.toml b/Cargo.toml index d64fcdd..f8c3d65 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ path = "src/main.rs" [dependencies] # Primary SDK for Hyperliquid API hypersdk = "0.2" -reqwest = { version = "0.13", features = ["blocking", "json"] } +reqwest = { version = "0.13", features = ["json"] } alloy-signer-local = { version = "2.0.4", features = ["keystore"] } # hypersdk 0.2 still re-exports Alloy 1.x signer types. Keep the v1 crates # feature-enabled until hypersdk moves to Alloy 2 so local keystores and diff --git a/src/bankr.rs b/src/bankr.rs index 83ae01c..aef61a2 100644 --- a/src/bankr.rs +++ b/src/bankr.rs @@ -5,6 +5,8 @@ //! and verifies the recovered signer address before accepting the signature. use std::env; +use std::future::Future; +use std::sync::OnceLock; use std::time::Duration; use alloy::dyn_abi::TypedData; @@ -179,25 +181,81 @@ fn wallet_address(api_base_url: &str, api_key: &str) -> Result Deserialize<'de>>( +fn bankr_http_client() -> Result<&'static reqwest::Client, CliError> { + static CLIENT: OnceLock> = OnceLock::new(); + CLIENT + .get_or_init(|| { + reqwest::Client::builder() + .timeout(DEFAULT_TIMEOUT) + .build() + .map_err(|err| err.to_string()) + }) + .as_ref() + .map_err(|err| CliError::Internal(anyhow::anyhow!("failed to build Bankr HTTP client: {err}"))) +} + +/// Run async Bankr HTTP from sync call sites (CLI signer resolution, examples, tests). +fn run_bankr_async(f: F) -> Result +where + F: FnOnce() -> Fut, + Fut: Future>, + T: Send, +{ + match tokio::runtime::Handle::try_current() { + Ok(handle) => tokio::task::block_in_place(|| handle.block_on(f())), + Err(_) => tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .map_err(|err| CliError::Internal(anyhow::anyhow!(err)))? + .block_on(f()), + } +} + +fn get_json Deserialize<'de> + Send>( + api_base_url: &str, + path: &str, + api_key: &str, + context: &'static str, +) -> Result { + let api_base_url = api_base_url.to_string(); + let api_key = api_key.to_string(); + run_bankr_async(move || async move { + get_json_async(&api_base_url, path, &api_key, context).await + }) +} + +async fn get_json_async Deserialize<'de> + Send>( api_base_url: &str, path: &str, api_key: &str, context: &'static str, ) -> Result { let url = bankr_url(api_base_url, path)?; - let response = reqwest::blocking::Client::builder() - .timeout(DEFAULT_TIMEOUT) - .build() - .map_err(|err| CliError::Internal(anyhow::anyhow!(err)))? + let response = bankr_http_client()? .get(url) .header("X-API-Key", api_key) .send() + .await .map_err(|err| CliError::Unavailable(format!("Check your network connection. {err}")))?; - decode_response(response, context) + decode_response(response, context).await } -fn post_json Deserialize<'de>>( +fn post_json Deserialize<'de> + Send>( + api_base_url: &str, + path: &str, + api_key: &str, + payload: &Value, + context: &'static str, +) -> Result { + let api_base_url = api_base_url.to_string(); + let api_key = api_key.to_string(); + let payload = payload.clone(); + run_bankr_async(move || async move { + post_json_async(&api_base_url, path, &api_key, &payload, context).await + }) +} + +async fn post_json_async Deserialize<'de> + Send>( api_base_url: &str, path: &str, api_key: &str, @@ -205,25 +263,24 @@ fn post_json Deserialize<'de>>( context: &'static str, ) -> Result { let url = bankr_url(api_base_url, path)?; - let response = reqwest::blocking::Client::builder() - .timeout(DEFAULT_TIMEOUT) - .build() - .map_err(|err| CliError::Internal(anyhow::anyhow!(err)))? + let response = bankr_http_client()? .post(url) .header("X-API-Key", api_key) .json(payload) .send() + .await .map_err(|err| CliError::Unavailable(format!("Check your network connection. {err}")))?; - decode_response(response, context) + decode_response(response, context).await } -fn decode_response Deserialize<'de>>( - response: reqwest::blocking::Response, +async fn decode_response Deserialize<'de> + Send>( + response: reqwest::Response, context: &'static str, ) -> Result { let status = response.status(); let body = response .text() + .await .map_err(|err| CliError::Unavailable(format!("Failed to read Bankr response. {err}")))?; ensure_bankr_success(status, &body)?; serde_json::from_str::(&body).map_err(|err| { @@ -250,9 +307,24 @@ fn ensure_bankr_success(status: StatusCode, body: &str) -> Result<(), CliError> body, ))); } + if status == StatusCode::BAD_REQUEST { + return Err(CliError::InvalidAuth(bankr_error_message( + "bankr_bad_request", + body, + ))); + } if !status.is_success() { - return Err(CliError::Unavailable(format!( - "Bankr API returned HTTP {status}. Check your network connection." + return Err(CliError::Unavailable(bankr_error_message( + "bankr_unavailable", + body, + ))); + } + if let Ok(value) = serde_json::from_str::(body) + && value.get("success") == Some(&Value::Bool(false)) + { + return Err(CliError::InvalidAuth(bankr_error_message( + "bankr_sign_failed", + body, ))); } Ok(()) @@ -295,6 +367,7 @@ fn bankr_typed_data_value(typed_data: &TypedData) -> Result { })?; ensure_eip712_domain_type(&mut value); pad_odd_hex_typed_values(&mut value); + normalize_bankr_numeric_fields(&mut value); Ok(value) } @@ -404,6 +477,102 @@ fn is_hex_encoded_eip712_scalar(field_type: &str) -> bool { || field_type.starts_with("int") } +fn normalize_bankr_numeric_fields(value: &mut Value) { + let Some(types) = value.get("types").and_then(Value::as_object).cloned() else { + return; + }; + if let Some(domain) = value.get_mut("domain") { + normalize_struct_bankr_numeric_fields("EIP712Domain", domain, &types); + } + let Some(primary_type) = value + .get("primaryType") + .and_then(Value::as_str) + .map(str::to_string) + else { + return; + }; + if let Some(message) = value.get_mut("message") { + normalize_struct_bankr_numeric_fields(&primary_type, message, &types); + } +} + +fn normalize_struct_bankr_numeric_fields( + type_name: &str, + value: &mut Value, + types: &serde_json::Map, +) { + let Some(fields) = types.get(type_name).and_then(Value::as_array).cloned() else { + return; + }; + let Some(object) = value.as_object_mut() else { + return; + }; + + for field in fields { + let Some(name) = field.get("name").and_then(Value::as_str) else { + continue; + }; + let Some(field_type) = field.get("type").and_then(Value::as_str) else { + continue; + }; + let Some(field_value) = object.get_mut(name) else { + continue; + }; + normalize_field_bankr_numeric_values(field_type, field_value, types); + } +} + +fn normalize_field_bankr_numeric_values( + field_type: &str, + value: &mut Value, + types: &serde_json::Map, +) { + if let Some(element_type) = field_type.strip_suffix("[]") { + if let Some(values) = value.as_array_mut() { + for value in values { + normalize_field_bankr_numeric_values(element_type, value, types); + } + } + return; + } + + if types.contains_key(field_type) { + normalize_struct_bankr_numeric_fields(field_type, value, types); + return; + } + + if is_eip712_integer_scalar(field_type) { + normalize_bankr_integer_scalar(value); + } +} + +fn is_eip712_integer_scalar(field_type: &str) -> bool { + field_type.starts_with("uint") || field_type.starts_with("int") +} + +fn normalize_bankr_integer_scalar(value: &mut Value) { + let Some(text) = value.as_str() else { + return; + }; + if let Some(number) = parse_bankr_integer_scalar(text) { + *value = serde_json::Number::from(number).into(); + } +} + +fn parse_bankr_integer_scalar(text: &str) -> Option { + let trimmed = text.trim(); + if trimmed.is_empty() { + return None; + } + if let Some(hex) = trimmed + .strip_prefix("0x") + .or_else(|| trimmed.strip_prefix("0X")) + { + return u64::from_str_radix(hex, 16).ok(); + } + trimmed.parse::().ok() +} + fn hyperliquid_signature_from_bankr( response: SignResponse, ) -> Result { @@ -539,7 +708,15 @@ mod tests { ) } - async fn run_blocking(f: impl FnOnce() -> T + Send + 'static) -> T { + #[test] + fn bankr_typed_data_value_normalizes_integer_fields_for_bankr_api() { + let typed_data = test_typed_data(); + let value = bankr_typed_data_value(&typed_data).unwrap(); + + assert_eq!(value["domain"]["chainId"], 999); + } + + async fn run_bankr(f: impl FnOnce() -> T + Send + 'static) -> T { tokio::task::spawn_blocking(f).await.unwrap() } @@ -561,7 +738,7 @@ mod tests { .await; let server_uri = server.uri(); - let address = run_blocking(move || wallet_address(&server_uri, API_KEY).unwrap()).await; + let address = run_bankr(move || wallet_address(&server_uri, API_KEY).unwrap()).await; assert_eq!(address, signer.address()); } @@ -586,7 +763,7 @@ mod tests { let server_uri = server.uri(); let typed_data_for_signing = typed_data.clone(); - let signature = run_blocking(move || { + let signature = run_bankr(move || { sign_typed_data(&config(server_uri), &typed_data_for_signing).unwrap() }) .await; @@ -623,7 +800,7 @@ mod tests { let server_uri = server.uri(); let typed_data_for_signing = typed_data.clone(); - let err = run_blocking(move || { + let err = run_bankr(move || { sign_typed_data(&config(server_uri), &typed_data_for_signing).unwrap_err() }) .await; @@ -652,7 +829,7 @@ mod tests { let server_uri = server.uri(); let signature = - run_blocking(move || sign_message(&config(server_uri), b"hello bankr").unwrap()).await; + run_bankr(move || sign_message(&config(server_uri), b"hello bankr").unwrap()).await; let recovered = signature.recover_address_from_msg(b"hello bankr").unwrap(); assert_eq!(recovered, signer.address()); @@ -685,7 +862,7 @@ mod tests { .await; let server_uri = server.uri(); - let err = run_blocking(move || wallet_address(&server_uri, API_KEY).unwrap_err()).await; + let err = run_bankr(move || wallet_address(&server_uri, API_KEY).unwrap_err()).await; assert_eq!(err.exit_code(), 10); assert!(err.to_string().contains("bankr_access_denied")); From 3d5c1ebd8de94b5f7196f09be1bbc67b179409ae Mon Sep 17 00:00:00 2001 From: Sayo <82053242+wtfsayo@users.noreply.github.com> Date: Thu, 21 May 2026 01:01:24 +0530 Subject: [PATCH 3/3] Fix Bankr catalog metadata and regenerate contract fixtures. Classify bankr_signer per command (unsupported_raw_l1_signing for auth-required mutating commands, address_selector_supported for wallet show/address, local_only for prio bid, not_applicable for local-only) so registry inference is not overridden incorrectly. Regenerate characterization fixtures and drop redundant bytes type check. Co-authored-by: Cursor --- src/bankr.rs | 13 +- src/command_catalog.json | 124 ++--- .../contracts/registry_inventory.json | 448 +++++++++--------- .../contracts/schema_high_risk_metadata.json | 224 ++++----- .../contracts/schema_representative.json | 48 +- 5 files changed, 429 insertions(+), 428 deletions(-) diff --git a/src/bankr.rs b/src/bankr.rs index aef61a2..f57f772 100644 --- a/src/bankr.rs +++ b/src/bankr.rs @@ -191,7 +191,9 @@ fn bankr_http_client() -> Result<&'static reqwest::Client, CliError> { .map_err(|err| err.to_string()) }) .as_ref() - .map_err(|err| CliError::Internal(anyhow::anyhow!("failed to build Bankr HTTP client: {err}"))) + .map_err(|err| { + CliError::Internal(anyhow::anyhow!("failed to build Bankr HTTP client: {err}")) + }) } /// Run async Bankr HTTP from sync call sites (CLI signer resolution, examples, tests). @@ -219,9 +221,9 @@ fn get_json Deserialize<'de> + Send>( ) -> Result { let api_base_url = api_base_url.to_string(); let api_key = api_key.to_string(); - run_bankr_async(move || async move { - get_json_async(&api_base_url, path, &api_key, context).await - }) + run_bankr_async( + move || async move { get_json_async(&api_base_url, path, &api_key, context).await }, + ) } async fn get_json_async Deserialize<'de> + Send>( @@ -471,8 +473,7 @@ fn pad_field_odd_hex_values( } fn is_hex_encoded_eip712_scalar(field_type: &str) -> bool { - field_type == "bytes" - || field_type.starts_with("bytes") + field_type.starts_with("bytes") || field_type.starts_with("uint") || field_type.starts_with("int") } diff --git a/src/command_catalog.json b/src/command_catalog.json index 0285374..d7c92bc 100644 --- a/src/command_catalog.json +++ b/src/command_catalog.json @@ -469,7 +469,7 @@ "raw_payload": "dry_run_only", "confirmation": "prompt", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid account fills
", @@ -836,7 +836,7 @@ "raw_payload": "dry_run_only", "confirmation": "prompt", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid subaccount list
", @@ -884,7 +884,7 @@ "raw_payload": "dry_run_only", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid subaccount transfer", @@ -932,7 +932,7 @@ "raw_payload": "dry_run_only", "confirmation": "prompt", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid subaccount spot-transfer", @@ -987,7 +987,7 @@ "raw_payload": "dry_run_only", "confirmation": "prompt", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid account ls", @@ -1002,7 +1002,7 @@ "raw_payload": "unsupported", "confirmation": "none", "ows_signer": "not_applicable", - "bankr_signer": "not_required" + "bankr_signer": "not_applicable" }, { "command": "hyperliquid account add ", @@ -1040,7 +1040,7 @@ "raw_payload": "unsupported", "confirmation": "prompt", "ows_signer": "not_applicable", - "bankr_signer": "not_required" + "bankr_signer": "not_applicable" }, { "command": "hyperliquid account set-default ", @@ -1062,7 +1062,7 @@ "raw_payload": "unsupported", "confirmation": "prompt", "ows_signer": "not_applicable", - "bankr_signer": "not_required" + "bankr_signer": "not_applicable" }, { "command": "hyperliquid account remove ", @@ -1092,7 +1092,7 @@ "raw_payload": "unsupported", "confirmation": "prompt", "ows_signer": "not_applicable", - "bankr_signer": "not_required" + "bankr_signer": "not_applicable" }, { "command": "hyperliquid api-wallet create", @@ -1131,7 +1131,7 @@ "raw_payload": "dry_run_only", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid api-wallet approve", @@ -1170,7 +1170,7 @@ "raw_payload": "dry_run_only", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid api-wallet list", @@ -1195,7 +1195,7 @@ "raw_payload": "unsupported", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid api-wallet revoke", @@ -1217,7 +1217,7 @@ "raw_payload": "dry_run_only", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid wallet create", @@ -1232,7 +1232,7 @@ "raw_payload": "unsupported", "confirmation": "none", "ows_signer": "not_applicable", - "bankr_signer": "not_required" + "bankr_signer": "not_applicable" }, { "command": "hyperliquid wallet import ", @@ -1253,7 +1253,7 @@ "raw_payload": "unsupported", "confirmation": "prompt", "ows_signer": "not_applicable", - "bankr_signer": "not_required" + "bankr_signer": "not_applicable" }, { "command": "hyperliquid wallet show", @@ -1268,7 +1268,7 @@ "raw_payload": "unsupported", "confirmation": "none", "ows_signer": "address_selector_supported", - "bankr_signer": "not_required" + "bankr_signer": "address_selector_supported" }, { "command": "hyperliquid wallet address", @@ -1283,7 +1283,7 @@ "raw_payload": "unsupported", "confirmation": "none", "ows_signer": "address_selector_supported", - "bankr_signer": "not_required" + "bankr_signer": "address_selector_supported" }, { "command": "hyperliquid wallet reset", @@ -1307,7 +1307,7 @@ "raw_payload": "unsupported", "confirmation": "prompt", "ows_signer": "not_applicable", - "bankr_signer": "not_required" + "bankr_signer": "not_applicable" }, { "command": "hyperliquid wallet import-mnemonic ", @@ -1333,7 +1333,7 @@ "raw_payload": "unsupported", "confirmation": "prompt", "ows_signer": "not_applicable", - "bankr_signer": "not_required" + "bankr_signer": "not_applicable" }, { "command": "hyperliquid wallet list", @@ -1348,7 +1348,7 @@ "raw_payload": "unsupported", "confirmation": "none", "ows_signer": "not_applicable", - "bankr_signer": "not_required" + "bankr_signer": "not_applicable" }, { "command": "hyperliquid wallet rename ", @@ -1376,7 +1376,7 @@ "raw_payload": "unsupported", "confirmation": "none", "ows_signer": "not_applicable", - "bankr_signer": "not_required" + "bankr_signer": "not_applicable" }, { "command": "hyperliquid wallet delete ", @@ -1406,7 +1406,7 @@ "raw_payload": "unsupported", "confirmation": "prompt", "ows_signer": "not_applicable", - "bankr_signer": "not_required" + "bankr_signer": "not_applicable" }, { "command": "hyperliquid wallet export ", @@ -1436,7 +1436,7 @@ "raw_payload": "unsupported", "confirmation": "prompt", "ows_signer": "not_applicable", - "bankr_signer": "not_required" + "bankr_signer": "not_applicable" }, { "command": "hyperliquid orders open", @@ -1465,7 +1465,7 @@ "raw_payload": "unsupported", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid orders history", @@ -1480,7 +1480,7 @@ "raw_payload": "unsupported", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid orders status", @@ -1553,7 +1553,7 @@ "raw_payload": "unsupported", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid staking validators", @@ -1879,7 +1879,7 @@ "raw_payload": "dry_run_only", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid borrowlend withdraw --amount ", @@ -1913,7 +1913,7 @@ "raw_payload": "dry_run_only", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid prio status", @@ -1943,7 +1943,7 @@ "raw_payload": "unsupported", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid orders create", @@ -2105,7 +2105,7 @@ "raw_payload": "dry_run_only", "confirmation": "prompt", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid orders scale", @@ -2211,7 +2211,7 @@ "raw_payload": "dry_run_only", "confirmation": "prompt", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid orders batch-create", @@ -2248,7 +2248,7 @@ "raw_payload": "dry_run_only", "confirmation": "prompt", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid orders tpsl", @@ -2336,7 +2336,7 @@ "raw_payload": "dry_run_only", "confirmation": "prompt", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid orders cancel ", @@ -2370,7 +2370,7 @@ "raw_payload": "dry_run_only", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid orders cancel-all", @@ -2412,7 +2412,7 @@ "raw_payload": "dry_run_only", "confirmation": "prompt", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid orders modify ", @@ -2473,7 +2473,7 @@ "raw_payload": "dry_run_only", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid orders twap-create", @@ -2550,7 +2550,7 @@ "raw_payload": "dry_run_only", "confirmation": "prompt", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid orders twap-cancel ", @@ -2593,7 +2593,7 @@ "raw_payload": "dry_run_only", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid positions update-leverage", @@ -2630,7 +2630,7 @@ "raw_payload": "dry_run_only", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid positions update-margin", @@ -2660,7 +2660,7 @@ "raw_payload": "dry_run_only", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid orders schedule-cancel", @@ -2704,7 +2704,7 @@ "raw_payload": "dry_run_only", "confirmation": "prompt", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid transfer spot-to-perp", @@ -2735,7 +2735,7 @@ "raw_payload": "dry_run_only", "confirmation": "prompt", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid transfer perp-to-spot", @@ -2766,7 +2766,7 @@ "raw_payload": "dry_run_only", "confirmation": "prompt", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid transfer send", @@ -2807,7 +2807,7 @@ "raw_payload": "dry_run_only", "confirmation": "prompt", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid transfer spot-send", @@ -2852,7 +2852,7 @@ "raw_payload": "dry_run_only", "confirmation": "prompt", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid transfer send-asset", @@ -2916,7 +2916,7 @@ "raw_payload": "dry_run_only", "confirmation": "prompt", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid transfer withdraw", @@ -2954,7 +2954,7 @@ "raw_payload": "dry_run_only", "confirmation": "prompt", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid staking delegate", @@ -2984,7 +2984,7 @@ "raw_payload": "dry_run_only", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid staking undelegate", @@ -3014,7 +3014,7 @@ "raw_payload": "dry_run_only", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid staking deposit", @@ -3037,7 +3037,7 @@ "raw_payload": "dry_run_only", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid staking withdraw", @@ -3060,7 +3060,7 @@ "raw_payload": "dry_run_only", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid staking claim-rewards", @@ -3075,7 +3075,7 @@ "raw_payload": "dry_run_only", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid staking link initiate", @@ -3106,7 +3106,7 @@ "raw_payload": "dry_run_only", "confirmation": "prompt", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid staking link finalize", @@ -3137,7 +3137,7 @@ "raw_payload": "dry_run_only", "confirmation": "prompt", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid vault deposit", @@ -3167,7 +3167,7 @@ "raw_payload": "dry_run_only", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid vault withdraw", @@ -3197,7 +3197,7 @@ "raw_payload": "dry_run_only", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid prio bid", @@ -3232,7 +3232,7 @@ "raw_payload": "dry_run_only", "confirmation": "none", "ows_signer": "local_only", - "bankr_signer": "not_required" + "bankr_signer": "local_only" }, { "command": "hyperliquid referral set ", @@ -3253,7 +3253,7 @@ "raw_payload": "dry_run_only", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid referral register ", @@ -3275,7 +3275,7 @@ "raw_payload": "dry_run_only", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid subscribe trades", @@ -3439,7 +3439,7 @@ "raw_payload": "unsupported", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid subscribe fills", @@ -3467,7 +3467,7 @@ "raw_payload": "unsupported", "confirmation": "none", "ows_signer": "experimental_feature_gated", - "bankr_signer": "not_required" + "bankr_signer": "unsupported_raw_l1_signing" }, { "command": "hyperliquid feedback", @@ -3597,7 +3597,7 @@ "raw_payload": "unsupported", "confirmation": "prompt", "ows_signer": "not_applicable", - "bankr_signer": "not_required" + "bankr_signer": "not_applicable" } ] } diff --git a/tests/fixtures/contracts/registry_inventory.json b/tests/fixtures/contracts/registry_inventory.json index d3044a0..51cae3e 100644 --- a/tests/fixtures/contracts/registry_inventory.json +++ b/tests/fixtures/contracts/registry_inventory.json @@ -4,6 +4,7 @@ { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid status", "command_path": [ "status" @@ -38,12 +39,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid meta", "command_path": [ "meta" @@ -78,12 +79,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid perps list", "command_path": [ "perps", @@ -133,12 +134,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid perps get ", "command_path": [ "perps", @@ -201,12 +202,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid spot list", "command_path": [ "spot", @@ -242,12 +243,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid spot get ", "command_path": [ "spot", @@ -297,12 +298,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid book ", "command_path": [ "book" @@ -377,12 +378,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid mids", "command_path": [ "mids" @@ -444,12 +445,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid candles ", "command_path": [ "candles" @@ -550,12 +551,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid spread ", "command_path": [ "spread" @@ -604,12 +605,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid funding ", "command_path": [ "funding" @@ -658,12 +659,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid asset decode ", "command_path": [ "asset", @@ -713,12 +714,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid asset search ", "command_path": [ "asset", @@ -781,12 +782,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid outcomes list", "command_path": [ "outcomes", @@ -836,12 +837,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid outcomes get ", "command_path": [ "outcomes", @@ -891,12 +892,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid builder max-fee", "command_path": [ "builder", @@ -959,12 +960,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid builder approved", "command_path": [ "builder", @@ -1014,12 +1015,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid builder approve", "command_path": [ "builder", @@ -1095,12 +1096,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid account fills
", "command_path": [ "account", @@ -1189,12 +1190,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid account fees
", "command_path": [ "account", @@ -1244,12 +1245,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid account rate-limit
", "command_path": [ "account", @@ -1299,12 +1300,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid account orders
", "command_path": [ "account", @@ -1354,12 +1355,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid account portfolio
", "command_path": [ "account", @@ -1409,12 +1410,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid account subaccounts
", "command_path": [ "account", @@ -1464,12 +1465,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid account portfolio-history
", "command_path": [ "account", @@ -1519,12 +1520,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid account ledger
", "command_path": [ "account", @@ -1600,12 +1601,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid account funding
", "command_path": [ "account", @@ -1681,12 +1682,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid account twap-history
", "command_path": [ "account", @@ -1736,12 +1737,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid account twap-fills
", "command_path": [ "account", @@ -1830,12 +1831,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid account abstraction
", "command_path": [ "account", @@ -1885,12 +1886,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid account abstraction set", "command_path": [ "account", @@ -1958,14 +1959,14 @@ "risk": "account_state", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [ "subaccounts" ], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid subaccount list
", "command_path": [ "subaccount", @@ -2015,14 +2016,14 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [ "subaccounts" ], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid subaccount create", "command_path": [ "subaccount", @@ -2072,14 +2073,14 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [ "subaccounts" ], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid subaccount transfer", "command_path": [ "subaccount", @@ -2171,14 +2172,14 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [ "subaccounts" ], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid subaccount spot-transfer", "command_path": [ "subaccount", @@ -2283,12 +2284,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid account ls", "command_path": [ "account", @@ -2324,12 +2325,12 @@ "risk": "local_state", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid account add ", "command_path": [ "account", @@ -2418,12 +2419,12 @@ "risk": "local_secret", "transport": [ "cli_interactive" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid account set-default ", "command_path": [ "account", @@ -2473,12 +2474,12 @@ "risk": "local_state", "transport": [ "cli_interactive" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid account remove ", "command_path": [ "account", @@ -2541,14 +2542,14 @@ "risk": "local_state", "transport": [ "cli_interactive" - ], - "bankr_signer": null + ] }, { "aliases": [ "api-wallets" ], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid api-wallet create", "command_path": [ "api-wallet", @@ -2637,14 +2638,14 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [ "api-wallets" ], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid api-wallet approve", "command_path": [ "api-wallet", @@ -2733,14 +2734,14 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [ "api-wallets" ], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid api-wallet list", "command_path": [ "api-wallet", @@ -2790,14 +2791,14 @@ "risk": "account_state", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [ "api-wallets" ], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid api-wallet revoke", "command_path": [ "api-wallet", @@ -2847,12 +2848,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid wallet create", "command_path": [ "wallet", @@ -2888,12 +2889,12 @@ "risk": "local_secret", "transport": [ "cli_interactive" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid wallet import ", "command_path": [ "wallet", @@ -2943,12 +2944,12 @@ "risk": "local_secret", "transport": [ "cli_interactive" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "address_selector_supported", "command": "hyperliquid wallet show", "command_path": [ "wallet", @@ -2984,12 +2985,12 @@ "risk": "local_secret", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "address_selector_supported", "command": "hyperliquid wallet address", "command_path": [ "wallet", @@ -3025,12 +3026,12 @@ "risk": "local_secret", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid wallet reset", "command_path": [ "wallet", @@ -3080,12 +3081,12 @@ "risk": "local_state", "transport": [ "cli_interactive" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid wallet import-mnemonic ", "command_path": [ "wallet", @@ -3148,12 +3149,12 @@ "risk": "local_secret", "transport": [ "cli_interactive" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid wallet list", "command_path": [ "wallet", @@ -3189,12 +3190,12 @@ "risk": "local_state", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid wallet rename ", "command_path": [ "wallet", @@ -3257,12 +3258,12 @@ "risk": "local_state", "transport": [ "cli_interactive" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid wallet delete ", "command_path": [ "wallet", @@ -3325,12 +3326,12 @@ "risk": "local_state", "transport": [ "cli_interactive" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid wallet export ", "command_path": [ "wallet", @@ -3393,12 +3394,12 @@ "risk": "local_secret", "transport": [ "cli_interactive" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders open", "command_path": [ "orders", @@ -3461,12 +3462,12 @@ "risk": "account_state", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders history", "command_path": [ "orders", @@ -3502,12 +3503,12 @@ "risk": "account_state", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid orders status", "command_path": [ "orders", @@ -3590,12 +3591,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid positions list", "command_path": [ "positions", @@ -3658,12 +3659,12 @@ "risk": "account_state", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid staking validators", "command_path": [ "staking", @@ -3699,12 +3700,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid staking summary
", "command_path": [ "staking", @@ -3754,12 +3755,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid staking rewards
", "command_path": [ "staking", @@ -3809,12 +3810,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid staking history
", "command_path": [ "staking", @@ -3864,14 +3865,14 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [ "vaults" ], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid vault list", "command_path": [ "vault", @@ -3972,14 +3973,14 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [ "vaults" ], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid vault search ", "command_path": [ "vault", @@ -4073,14 +4074,14 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [ "vaults" ], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid vault get
", "command_path": [ "vault", @@ -4130,14 +4131,14 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [ "vaults" ], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid vault positions
", "command_path": [ "vault", @@ -4187,12 +4188,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid borrowlend rates", "command_path": [ "borrowlend", @@ -4228,12 +4229,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid borrowlend get ", "command_path": [ "borrowlend", @@ -4283,12 +4284,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid borrowlend user
", "command_path": [ "borrowlend", @@ -4338,12 +4339,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid borrowlend supply --amount ", "command_path": [ "borrowlend", @@ -4406,12 +4407,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid borrowlend withdraw --amount ", "command_path": [ "borrowlend", @@ -4487,12 +4488,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid prio status", "command_path": [ "prio", @@ -4528,12 +4529,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid referral status", "command_path": [ "referral", @@ -4569,12 +4570,12 @@ "risk": "account_state", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders create", "command_path": [ "orders", @@ -4890,12 +4891,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders scale", "command_path": [ "orders", @@ -5098,12 +5099,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders batch-create", "command_path": [ "orders", @@ -5179,12 +5180,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders tpsl", "command_path": [ "orders", @@ -5359,12 +5360,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders cancel ", "command_path": [ "orders", @@ -5440,12 +5441,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders cancel-all", "command_path": [ "orders", @@ -5534,12 +5535,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders modify ", "command_path": [ "orders", @@ -5661,12 +5662,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders twap-create", "command_path": [ "orders", @@ -5813,12 +5814,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders twap-cancel ", "command_path": [ "orders", @@ -5907,12 +5908,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid positions update-leverage", "command_path": [ "positions", @@ -5988,12 +5989,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid positions update-margin", "command_path": [ "positions", @@ -6056,12 +6057,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders schedule-cancel", "command_path": [ "orders", @@ -6150,14 +6151,14 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [ "transfers" ], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid transfer spot-to-perp", "command_path": [ "transfer", @@ -6220,14 +6221,14 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [ "transfers" ], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid transfer perp-to-spot", "command_path": [ "transfer", @@ -6290,14 +6291,14 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [ "transfers" ], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid transfer send", "command_path": [ "transfer", @@ -6373,14 +6374,14 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [ "transfers" ], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid transfer spot-send", "command_path": [ "transfer", @@ -6469,14 +6470,14 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [ "transfers" ], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid transfer send-asset", "command_path": [ "transfer", @@ -6604,14 +6605,14 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [ "transfers" ], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid transfer withdraw", "command_path": [ "transfer", @@ -6687,12 +6688,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid staking delegate", "command_path": [ "staking", @@ -6755,12 +6756,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid staking undelegate", "command_path": [ "staking", @@ -6823,12 +6824,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid staking deposit", "command_path": [ "staking", @@ -6878,12 +6879,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid staking withdraw", "command_path": [ "staking", @@ -6933,12 +6934,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid staking claim-rewards", "command_path": [ "staking", @@ -6974,12 +6975,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid staking link initiate", "command_path": [ "staking", @@ -7043,12 +7044,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid staking link finalize", "command_path": [ "staking", @@ -7112,14 +7113,14 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [ "vaults" ], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid vault deposit", "command_path": [ "vault", @@ -7182,14 +7183,14 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [ "vaults" ], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid vault withdraw", "command_path": [ "vault", @@ -7252,12 +7253,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "local_only", "command": "hyperliquid prio bid", "command_path": [ "prio", @@ -7333,12 +7334,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid referral set ", "command_path": [ "referral", @@ -7388,12 +7389,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid referral register ", "command_path": [ "referral", @@ -7443,12 +7444,12 @@ "risk": "funds_movement", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid subscribe trades", "command_path": [ "subscribe", @@ -7524,12 +7525,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid subscribe orderbook", "command_path": [ "subscribe", @@ -7605,12 +7606,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid subscribe candles", "command_path": [ "subscribe", @@ -7699,12 +7700,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid subscribe all-mids", "command_path": [ "subscribe", @@ -7767,12 +7768,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid subscribe order-updates", "command_path": [ "subscribe", @@ -7835,12 +7836,12 @@ "risk": "account_state", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid subscribe fills", "command_path": [ "subscribe", @@ -7903,12 +7904,12 @@ "risk": "account_state", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid feedback", "command_path": [ "feedback" @@ -8016,12 +8017,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid schema", "command_path": [ "schema" @@ -8070,12 +8071,12 @@ "risk": "none", "transport": [ "cli_process" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid update", "command_path": [ "update" @@ -8110,12 +8111,12 @@ "risk": "local_state", "transport": [ "cli_interactive" - ], - "bankr_signer": null + ] }, { "aliases": [], "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid setup", "command_path": [ "setup" @@ -8190,8 +8191,7 @@ "risk": "local_secret", "transport": [ "cli_interactive" - ], - "bankr_signer": null + ] } ], "review_required_to_update": true diff --git a/tests/fixtures/contracts/schema_high_risk_metadata.json b/tests/fixtures/contracts/schema_high_risk_metadata.json index f1e762a..897ed7c 100644 --- a/tests/fixtures/contracts/schema_high_risk_metadata.json +++ b/tests/fixtures/contracts/schema_high_risk_metadata.json @@ -3,6 +3,7 @@ "commands": [ { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid builder approve", "confirmation": "prompt", "dangerous": true, @@ -10,11 +11,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid account abstraction set", "confirmation": "prompt", "dangerous": true, @@ -22,11 +23,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "account_state", - "bankr_signer": "not_required" + "risk": "account_state" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid subaccount create", "confirmation": "none", "dangerous": true, @@ -34,11 +35,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid subaccount transfer", "confirmation": "prompt", "dangerous": true, @@ -46,11 +47,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid subaccount spot-transfer", "confirmation": "prompt", "dangerous": true, @@ -58,11 +59,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid account ls", "confirmation": "none", "dangerous": false, @@ -70,11 +71,11 @@ "lifecycle": "read_only", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_state", - "bankr_signer": "not_required" + "risk": "local_state" }, { "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid account add ", "confirmation": "prompt", "dangerous": true, @@ -82,11 +83,11 @@ "lifecycle": "interactive_local", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_secret", - "bankr_signer": "not_required" + "risk": "local_secret" }, { "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid account set-default ", "confirmation": "prompt", "dangerous": true, @@ -94,11 +95,11 @@ "lifecycle": "interactive_local", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_state", - "bankr_signer": "not_required" + "risk": "local_state" }, { "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid account remove ", "confirmation": "prompt", "dangerous": true, @@ -106,11 +107,11 @@ "lifecycle": "interactive_local", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_state", - "bankr_signer": "not_required" + "risk": "local_state" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid api-wallet create", "confirmation": "none", "dangerous": true, @@ -118,11 +119,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid api-wallet approve", "confirmation": "none", "dangerous": true, @@ -130,11 +131,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid api-wallet revoke", "confirmation": "none", "dangerous": true, @@ -142,11 +143,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid wallet create", "confirmation": "none", "dangerous": true, @@ -154,11 +155,11 @@ "lifecycle": "interactive_local", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_secret", - "bankr_signer": "not_required" + "risk": "local_secret" }, { "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid wallet import ", "confirmation": "prompt", "dangerous": true, @@ -166,11 +167,11 @@ "lifecycle": "interactive_local", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_secret", - "bankr_signer": "not_required" + "risk": "local_secret" }, { "auth_required": true, + "bankr_signer": "address_selector_supported", "command": "hyperliquid wallet show", "confirmation": "none", "dangerous": false, @@ -178,11 +179,11 @@ "lifecycle": "read_only", "ows_signer": "address_selector_supported", "raw_payload": "unsupported", - "risk": "local_secret", - "bankr_signer": "not_required" + "risk": "local_secret" }, { "auth_required": true, + "bankr_signer": "address_selector_supported", "command": "hyperliquid wallet address", "confirmation": "none", "dangerous": false, @@ -190,11 +191,11 @@ "lifecycle": "read_only", "ows_signer": "address_selector_supported", "raw_payload": "unsupported", - "risk": "local_secret", - "bankr_signer": "not_required" + "risk": "local_secret" }, { "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid wallet reset", "confirmation": "prompt", "dangerous": true, @@ -202,11 +203,11 @@ "lifecycle": "interactive_local", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_state", - "bankr_signer": "not_required" + "risk": "local_state" }, { "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid wallet import-mnemonic ", "confirmation": "prompt", "dangerous": true, @@ -214,11 +215,11 @@ "lifecycle": "interactive_local", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_secret", - "bankr_signer": "not_required" + "risk": "local_secret" }, { "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid wallet list", "confirmation": "none", "dangerous": false, @@ -226,11 +227,11 @@ "lifecycle": "read_only", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_state", - "bankr_signer": "not_required" + "risk": "local_state" }, { "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid wallet rename ", "confirmation": "none", "dangerous": true, @@ -238,11 +239,11 @@ "lifecycle": "interactive_local", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_state", - "bankr_signer": "not_required" + "risk": "local_state" }, { "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid wallet delete ", "confirmation": "prompt", "dangerous": true, @@ -250,11 +251,11 @@ "lifecycle": "interactive_local", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_state", - "bankr_signer": "not_required" + "risk": "local_state" }, { "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid wallet export ", "confirmation": "prompt", "dangerous": true, @@ -262,11 +263,11 @@ "lifecycle": "interactive_local", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_secret", - "bankr_signer": "not_required" + "risk": "local_secret" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid borrowlend supply --amount ", "confirmation": "none", "dangerous": true, @@ -274,11 +275,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid borrowlend withdraw --amount ", "confirmation": "none", "dangerous": true, @@ -286,11 +287,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders create", "confirmation": "prompt", "dangerous": true, @@ -298,11 +299,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders scale", "confirmation": "prompt", "dangerous": true, @@ -310,11 +311,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders batch-create", "confirmation": "prompt", "dangerous": true, @@ -322,11 +323,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders tpsl", "confirmation": "prompt", "dangerous": true, @@ -334,11 +335,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders cancel ", "confirmation": "none", "dangerous": true, @@ -346,11 +347,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders cancel-all", "confirmation": "prompt", "dangerous": true, @@ -358,11 +359,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders modify ", "confirmation": "none", "dangerous": true, @@ -370,11 +371,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders twap-create", "confirmation": "prompt", "dangerous": true, @@ -382,11 +383,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders twap-cancel ", "confirmation": "none", "dangerous": true, @@ -394,11 +395,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid positions update-leverage", "confirmation": "none", "dangerous": true, @@ -406,11 +407,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid positions update-margin", "confirmation": "none", "dangerous": true, @@ -418,11 +419,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders schedule-cancel", "confirmation": "prompt", "dangerous": true, @@ -430,11 +431,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid transfer spot-to-perp", "confirmation": "prompt", "dangerous": true, @@ -442,11 +443,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid transfer perp-to-spot", "confirmation": "prompt", "dangerous": true, @@ -454,11 +455,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid transfer send", "confirmation": "prompt", "dangerous": true, @@ -466,11 +467,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid transfer spot-send", "confirmation": "prompt", "dangerous": true, @@ -478,11 +479,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid transfer send-asset", "confirmation": "prompt", "dangerous": true, @@ -490,11 +491,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid transfer withdraw", "confirmation": "prompt", "dangerous": true, @@ -502,11 +503,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid staking delegate", "confirmation": "none", "dangerous": true, @@ -514,11 +515,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid staking undelegate", "confirmation": "none", "dangerous": true, @@ -526,11 +527,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid staking deposit", "confirmation": "none", "dangerous": true, @@ -538,11 +539,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid staking withdraw", "confirmation": "none", "dangerous": true, @@ -550,11 +551,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid staking claim-rewards", "confirmation": "none", "dangerous": true, @@ -562,11 +563,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid staking link initiate", "confirmation": "prompt", "dangerous": true, @@ -574,11 +575,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid staking link finalize", "confirmation": "prompt", "dangerous": true, @@ -586,11 +587,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid vault deposit", "confirmation": "none", "dangerous": true, @@ -598,11 +599,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid vault withdraw", "confirmation": "none", "dangerous": true, @@ -610,11 +611,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "local_only", "command": "hyperliquid prio bid", "confirmation": "none", "dangerous": true, @@ -622,11 +623,11 @@ "lifecycle": "live_mutating", "ows_signer": "local_only", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid referral set ", "confirmation": "none", "dangerous": true, @@ -634,11 +635,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid referral register ", "confirmation": "none", "dangerous": true, @@ -646,11 +647,11 @@ "lifecycle": "live_mutating", "ows_signer": "experimental_feature_gated", "raw_payload": "dry_run_only", - "risk": "funds_movement", - "bankr_signer": "not_required" + "risk": "funds_movement" }, { "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid update", "confirmation": "none", "dangerous": true, @@ -658,11 +659,11 @@ "lifecycle": "interactive_local", "ows_signer": "not_required", "raw_payload": "unsupported", - "risk": "local_state", - "bankr_signer": "not_required" + "risk": "local_state" }, { "auth_required": false, + "bankr_signer": "not_applicable", "command": "hyperliquid setup", "confirmation": "prompt", "dangerous": true, @@ -670,8 +671,7 @@ "lifecycle": "interactive_local", "ows_signer": "not_applicable", "raw_payload": "unsupported", - "risk": "local_secret", - "bankr_signer": "not_required" + "risk": "local_secret" } ], "review_required_to_update": true diff --git a/tests/fixtures/contracts/schema_representative.json b/tests/fixtures/contracts/schema_representative.json index 08a85c4..4e3b9a4 100644 --- a/tests/fixtures/contracts/schema_representative.json +++ b/tests/fixtures/contracts/schema_representative.json @@ -285,6 +285,7 @@ } ], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders create", "command_path": [ "orders", @@ -430,6 +431,7 @@ "type": "object", "x-hyperliquid": { "aliases": [], + "bankr_signer": "unsupported_raw_l1_signing", "confirmation": "prompt", "confirmation_bypass": { "arg": "yes", @@ -445,8 +447,7 @@ "stream_bounds": null, "transport": [ "cli_process" - ], - "bankr_signer": "not_required" + ] } }, "lifecycle": "live_mutating", @@ -458,8 +459,7 @@ "stream_bounds": null, "transport": [ "cli_process" - ], - "bankr_signer": "not_required" + ] }, { "aliases": [], @@ -544,6 +544,7 @@ } ], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid orders modify ", "command_path": [ "orders", @@ -607,6 +608,7 @@ "type": "object", "x-hyperliquid": { "aliases": [], + "bankr_signer": "unsupported_raw_l1_signing", "confirmation": "none", "confirmation_bypass": { "arg": null, @@ -622,8 +624,7 @@ "stream_bounds": null, "transport": [ "cli_process" - ], - "bankr_signer": "not_required" + ] } }, "lifecycle": "live_mutating", @@ -635,8 +636,7 @@ "stream_bounds": null, "transport": [ "cli_process" - ], - "bankr_signer": "not_required" + ] }, { "aliases": [ @@ -684,6 +684,7 @@ } ], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid transfer send", "command_path": [ "transfer", @@ -726,6 +727,7 @@ "aliases": [ "transfers" ], + "bankr_signer": "unsupported_raw_l1_signing", "confirmation": "prompt", "confirmation_bypass": { "arg": "yes", @@ -741,8 +743,7 @@ "stream_bounds": null, "transport": [ "cli_process" - ], - "bankr_signer": "not_required" + ] } }, "lifecycle": "live_mutating", @@ -754,13 +755,13 @@ "stream_bounds": null, "transport": [ "cli_process" - ], - "bankr_signer": "not_required" + ] }, { "aliases": [], "args": [], "auth_required": true, + "bankr_signer": "address_selector_supported", "command": "hyperliquid wallet address", "command_path": [ "wallet", @@ -781,6 +782,7 @@ "type": "object", "x-hyperliquid": { "aliases": [], + "bankr_signer": "address_selector_supported", "confirmation": "none", "confirmation_bypass": { "arg": null, @@ -796,8 +798,7 @@ "stream_bounds": null, "transport": [ "cli_process" - ], - "bankr_signer": "not_required" + ] } }, "lifecycle": "read_only", @@ -809,8 +810,7 @@ "stream_bounds": null, "transport": [ "cli_process" - ], - "bankr_signer": "not_required" + ] }, { "aliases": [], @@ -843,6 +843,7 @@ } ], "auth_required": true, + "bankr_signer": "unsupported_raw_l1_signing", "command": "hyperliquid borrowlend supply --amount ", "command_path": [ "borrowlend", @@ -878,6 +879,7 @@ "type": "object", "x-hyperliquid": { "aliases": [], + "bankr_signer": "unsupported_raw_l1_signing", "confirmation": "none", "confirmation_bypass": { "arg": null, @@ -893,8 +895,7 @@ "stream_bounds": null, "transport": [ "cli_process" - ], - "bankr_signer": "not_required" + ] } }, "lifecycle": "live_mutating", @@ -906,8 +907,7 @@ "stream_bounds": null, "transport": [ "cli_process" - ], - "bankr_signer": "not_required" + ] }, { "aliases": [], @@ -940,6 +940,7 @@ } ], "auth_required": false, + "bankr_signer": "not_required", "command": "hyperliquid subscribe all-mids", "command_path": [ "subscribe", @@ -969,6 +970,7 @@ "type": "object", "x-hyperliquid": { "aliases": [], + "bankr_signer": "not_required", "confirmation": "none", "confirmation_bypass": { "arg": null, @@ -994,8 +996,7 @@ }, "transport": [ "cli_process" - ], - "bankr_signer": "not_required" + ] } }, "lifecycle": "streaming", @@ -1017,8 +1018,7 @@ }, "transport": [ "cli_process" - ], - "bankr_signer": "not_required" + ] } ], "review_required_to_update": true