From 93eca78d832baab56ca67776715939c20159efcb Mon Sep 17 00:00:00 2001 From: Amos Date: Thu, 7 May 2026 17:57:05 +0800 Subject: [PATCH] fix(hyperliquid-plugin): biz-type/strategy attribution + 1-place EVM-012 fix (v0.4.4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add `--biz-type dapp --strategy hyperliquid-plugin` to every onchainos `wallet contract-call` invocation so the OKX backend can attribute contract calls to this plugin. Source-of-truth for the strategy name is Cargo.toml's `[package].name` via `env!("CARGO_PKG_NAME")` — no drift between Cargo.toml, plugin.yaml, plugin.json. Affected onchainos call sites (5): - commands/get_gas.rs: USDC approve to relay solver - commands/get_gas.rs: USDC deposit through relay - commands/deposit.rs: USDC deposit on Hyperliquid bridge - commands/evm_send.rs: perp → spot transfer - commands/evm_send.rs: spot → EVM transfer Note: hyperliquid's perp order / cancel / TPSL paths use `onchainos wallet sign-message` (EIP-712), which doesn't accept biz-type/strategy. Only the contract-call paths can be attributed under the current onchainos 3.0.0 CLI. Also fix one real EVM-012 (silent RPC error swallowing): - commands/get_gas.rs:160 — `erc20_allowance(...).unwrap_or(0)` silently returned 0 on RPC failure, triggering an unnecessary re-approve. Changed to fail-closed `match` returning RPC_ERROR with stdout JSON for the calling Agent. Other `unwrap_or(0)` sites are JSON-field fallbacks for display-only fields (positions / orders / spot_prices) and intentional system-clock fallback in outcome_sell.rs — not real EVM-012. EVM-006 sleep sites are intentional polling (wait_tx_mined receipt poll, relay status poll) — these are correct patterns. Version bump: 0.4.3 → 0.4.4 (PATCH — backwards-compatible). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../.claude-plugin/plugin.json | 2 +- skills/hyperliquid-plugin/Cargo.lock | 2 +- skills/hyperliquid-plugin/Cargo.toml | 2 +- skills/hyperliquid-plugin/SKILL.md | 2 +- skills/hyperliquid-plugin/plugin.yaml | 2 +- .../hyperliquid-plugin/src/commands/get_gas.rs | 18 ++++++++++++++---- skills/hyperliquid-plugin/src/onchainos.rs | 9 +++++++++ 7 files changed, 28 insertions(+), 9 deletions(-) diff --git a/skills/hyperliquid-plugin/.claude-plugin/plugin.json b/skills/hyperliquid-plugin/.claude-plugin/plugin.json index 0d3bcac04..53204c377 100644 --- a/skills/hyperliquid-plugin/.claude-plugin/plugin.json +++ b/skills/hyperliquid-plugin/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "hyperliquid-plugin", "description": "Hyperliquid on-chain perpetuals DEX — check positions, get market prices, place and cancel perpetual orders on Hyperliquid L1 (chain_id 999).", - "version": "0.4.3", + "version": "0.4.4", "author": { "name": "GeoGu360", "github": "GeoGu360" diff --git a/skills/hyperliquid-plugin/Cargo.lock b/skills/hyperliquid-plugin/Cargo.lock index 476f6972b..30e5b15aa 100644 --- a/skills/hyperliquid-plugin/Cargo.lock +++ b/skills/hyperliquid-plugin/Cargo.lock @@ -591,7 +591,7 @@ dependencies = [ [[package]] name = "hyperliquid-plugin" -version = "0.4.3" +version = "0.4.4" dependencies = [ "anyhow", "clap", diff --git a/skills/hyperliquid-plugin/Cargo.toml b/skills/hyperliquid-plugin/Cargo.toml index ed36de111..8d3eec6a7 100644 --- a/skills/hyperliquid-plugin/Cargo.toml +++ b/skills/hyperliquid-plugin/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hyperliquid-plugin" -version = "0.4.3" +version = "0.4.4" edition = "2021" [[bin]] diff --git a/skills/hyperliquid-plugin/SKILL.md b/skills/hyperliquid-plugin/SKILL.md index ff482d431..4dc4e892f 100644 --- a/skills/hyperliquid-plugin/SKILL.md +++ b/skills/hyperliquid-plugin/SKILL.md @@ -1,7 +1,7 @@ --- name: hyperliquid-plugin description: Hyperliquid DEX — trade perps & spot, deposit from Arbitrum, withdraw to Arbitrum, transfer between perp and spot accounts, manage gas on HyperEVM. -version: "0.4.3" +version: "0.4.4" author: GeoGu360 tags: - perps diff --git a/skills/hyperliquid-plugin/plugin.yaml b/skills/hyperliquid-plugin/plugin.yaml index a8e7351d3..74ce950a9 100644 --- a/skills/hyperliquid-plugin/plugin.yaml +++ b/skills/hyperliquid-plugin/plugin.yaml @@ -1,6 +1,6 @@ schema_version: 1 name: hyperliquid-plugin -version: "0.4.3" +version: "0.4.4" description: "Trade perpetuals on Hyperliquid - check positions, get prices, place market/limit orders with TP/SL brackets, close positions, deposit USDC" author: name: GeoGu360 diff --git a/skills/hyperliquid-plugin/src/commands/get_gas.rs b/skills/hyperliquid-plugin/src/commands/get_gas.rs index b9e405aa2..6aa0dac15 100644 --- a/skills/hyperliquid-plugin/src/commands/get_gas.rs +++ b/skills/hyperliquid-plugin/src/commands/get_gas.rs @@ -154,10 +154,20 @@ pub async fn run(args: GetGasArgs) -> anyhow::Result<()> { let approve_calldata = data["data"].as_str().unwrap_or(""); let approve_value = parse_wei(data["value"].as_str().unwrap_or("0x0")); - // Skip if allowance is already sufficient - let existing = erc20_allowance(USDC_ARBITRUM, &wallet, approve_to, ARBITRUM_RPC) - .await - .unwrap_or(0); + // Skip if allowance is already sufficient. + // EVM-012: surface RPC errors instead of silent unwrap_or(0) — that turned + // a transient publicnode hiccup into an unnecessary re-approve. + let existing = match erc20_allowance(USDC_ARBITRUM, &wallet, approve_to, ARBITRUM_RPC).await { + Ok(v) => v, + Err(e) => { + println!("{}", super::error_response( + &format!("Failed to read USDC allowance for relay solver {}: {:#}", approve_to, e), + "RPC_ERROR", + "Public Arbitrum RPC may be limited; retry shortly.", + )); + return Ok(()); + } + }; if existing < usdc_units as u128 { eprintln!("Approving USDC to relay solver..."); diff --git a/skills/hyperliquid-plugin/src/onchainos.rs b/skills/hyperliquid-plugin/src/onchainos.rs index d7f542d6d..a792d4056 100644 --- a/skills/hyperliquid-plugin/src/onchainos.rs +++ b/skills/hyperliquid-plugin/src/onchainos.rs @@ -2,6 +2,11 @@ use std::process::Command; use serde_json::Value; use sha3::{Digest, Keccak256}; +/// `--biz-type` / `--strategy`: attribution to the onchainos backend. +/// Source-of-truth for the plugin name is Cargo.toml's `[package]` `name`. +const BIZ_TYPE: &str = "dapp"; +const STRATEGY: &str = env!("CARGO_PKG_NAME"); + /// Execute an EVM contract call via onchainos wallet contract-call. /// chain_id: the EVM chain (e.g. 42161 for Arbitrum). /// to: contract address. @@ -29,6 +34,10 @@ pub fn wallet_contract_call( let mut args = vec![ "wallet".to_string(), "contract-call".to_string(), + "--biz-type".to_string(), + BIZ_TYPE.to_string(), + "--strategy".to_string(), + STRATEGY.to_string(), "--chain".to_string(), chain_id.to_string(), "--to".to_string(),