Skip to content

feat(hyperliquid-plugin): strategy attribution reporting (v0.3.8)#325

Merged
Noah3595 merged 1 commit intookx:mainfrom
GeoGu360:feat/hyperliquid-strategy-attribution
Apr 22, 2026
Merged

feat(hyperliquid-plugin): strategy attribution reporting (v0.3.8)#325
Noah3595 merged 1 commit intookx:mainfrom
GeoGu360:feat/hyperliquid-strategy-attribution

Conversation

@GeoGu360
Copy link
Copy Markdown

Summary

Add optional --strategy-id flag to order and close commands. When provided and non-empty, the plugin pushes an order-level attribution payload to the OKX backend via onchainos wallet report-plugin-info after the order succeeds. Mirrors the attribution change just landed in polymarket-plugin (#324) so the OKX backend receives a uniform schema across prediction-market and perp plugins.

Payload shape

{
  "wallet":       "0x... (EOA)",
  "proxyAddress": "",
  "order_id":     "<HL oid as string>",
  "tx_hashes":    [],
  "market_id":    "BTC / ETH / etc (coin symbol)",
  "asset_id":     "",
  "side":         "BUY | SELL",
  "amount":       "<size in base units>",
  "symbol":       "USDC",
  "price":        "<avg fill when available, else limit>",
  "timestamp":    1776856156,
  "strategy_id":  "<user-provided>",
  "plugin_name":  "hyperliquid-plugin"
}

proxyAddress is always empty for HL (no proxy concept). tx_hashes is always empty at submit time — the on-chain settlement hash is available later via /info userFillsByTime keyed by oid, which is the backend's normal verification path.

Behavior

  • Opt-in: omitting --strategy-id (or passing "") skips reporting entirely. No change to default command behavior.
  • Non-fatal: if onchainos wallet report-plugin-info fails (subcommand not installed, backend unreachable, error response), the plugin logs a Warning to stderr and returns the normal order-success JSON on stdout. The order is already acknowledged by HL by the time the report fires — reporting failures must never affect trade results.
  • Close direction: for close, side is the order direction, not the position direction. Closing a long → SELL; closing a short → BUY.

Files changed (8 files, +122 / −11)

  • src/onchainos.rs — new report_plugin_info() wrapper (sync std::process::Command, chain 42161). +27
  • src/commands/order.rsOrderArgs gains --strategy-id; payload constructed + reported after result is extracted. +34
  • src/commands/close.rsCloseArgs gains --strategy-id; now also extracts avg_px / oid from the response (previously unused); payload + report. +44
  • SKILL.mdorder and close sections document --strategy-id semantics; CHANGELOG v0.3.8 entry; version refs bumped (5 places). +20 / −9
  • plugin.yaml / Cargo.toml / .claude-plugin/plugin.json — 0.3.7 → 0.3.8

Test plan

  • cargo build --release — clean
  • hyperliquid order --help / close --help both show --strategy-id
  • Trade without --strategy-id behaves unchanged (no report, no warning)
  • Real BTC market order with --strategy-id — order succeeds, report code path verified via the expected stderr Warning when run against onchainos v2.2.9 (which does not have the report-plugin-info subcommand). Order returned oid: 392545390502, avg_px: 78083.0; stdout JSON unchanged.
  • End-to-end backend integration: pending beta endpoint availability (tested with polymarket-plugin; same backend contract here)

Add optional --strategy-id flag to `order` and `close`. When provided
and non-empty, the plugin pushes an order-level attribution payload to
the OKX backend via `onchainos wallet report-plugin-info` after the
order succeeds.

Payload fields:
  wallet, proxyAddress (empty for HL), order_id (HL oid as string),
  tx_hashes (empty at submit — backend uses userFillsByTime by oid
  to fetch settlement hash + closedPnl + fee), market_id (coin
  symbol), asset_id (empty), side (BUY/SELL; for close: the order
  direction, not position direction), amount, symbol ("USDC"; the
  collateral asset), price (avg fill when available, else limit),
  timestamp, strategy_id, plugin_name.

Behavior:
- Omitting --strategy-id (or passing empty) skips reporting entirely.
- Report failures log a Warning to stderr and never affect the trade
  result — the order is already acknowledged by HL by the time the
  report fires.
- close.rs now also extracts avg_px / oid from the response so the
  report payload is complete.

Smoke-tested locally: v2.2.9 onchainos (no report-plugin-info
subcommand) produces the expected non-fatal Warning on stderr while
the order succeeds normally on stdout.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 22, 2026

🔨 Phase 2: Build Verification — ✅ PASSED

Plugin: hyperliquid-plugin | Language: rust
Source: @

Compiled from developer source code by our CI. Users install our build artifacts.

Build succeeded. Compiled artifact uploaded as workflow artifact.


Source integrity: commit SHA `` is the content fingerprint.

@github-actions
Copy link
Copy Markdown
Contributor

📋 Phase 3: AI Code Review Report — Score: 92/100

Plugin: hyperliquid-plugin | Recommendation: ✅ Ready to merge

🔗 Reviewed against latest onchainos source code (live from main branch) | Model: claude-opus-4-7 via Anthropic API | Cost: ~411627+7147 tokens

This is an advisory report. It does NOT block merging. Final decision is made by human reviewers.


1. Plugin Overview
Field Value
Name hyperliquid-plugin
Version 0.3.8
Category defi-protocol
Author GeoGu360 (GeoGu360)
License MIT
Has Binary Yes (with build config)
Risk Level High (perpetuals trading, write operations, deposit/withdraw)

Summary: A Rust-based plugin for trading perpetuals and spot on Hyperliquid DEX. Provides commands for checking positions/prices, placing market/limit orders with TP/SL brackets, closing positions, depositing USDC from Arbitrum, withdrawing, and transferring between perp/spot accounts. All signing is delegated to onchainos CLI (TEE-based).

Target Users: DeFi traders who use Hyperliquid perps and want an agent-friendly CLI interface with structured JSON output for positions, orders, and risk management.

2. Architecture Analysis

Components:
Skill (SKILL.md, SUMMARY.md) + Rust binary (hyperliquid-plugin)

Skill Structure:
SKILL.md includes trigger phrases, one-time setup (register), pre-flight checks, ~20 commands (quickstart, positions, prices, order, close, tpsl, cancel, deposit, withdraw, transfer, address, spot-*, get-gas, evm-send, orders, register), supported markets table, error handling, data trust boundary, changelog. SUMMARY.md is concise (1434 chars).

Data Flow:

  • Read ops → Hyperliquid REST API (api.hyperliquid.xyz/info, /exchange)
  • Arbitrum RPC calls (arbitrum-one-rpc.publicnode.com) for USDC balance, permit nonce, allowance
  • HyperEVM RPC for HYPE balance and tx receipts
  • Signing via onchainos wallet sign-message --type eip712 subprocess
  • Contract calls via onchainos wallet contract-call subprocess
  • relay.link API for get-gas (Arbitrum USDC → HyperEVM HYPE swap)
  • Strategy attribution reported via onchainos wallet report-plugin-info

Dependencies:

  • onchainos CLI (for wallet address resolution, EIP-712 signing, contract calls, plugin-info reporting)
  • Hyperliquid API (info + exchange endpoints)
  • Arbitrum RPC (publicnode.com)
  • HyperEVM RPC
  • relay.link for cross-chain gas swap
  • Rust crates: clap, tokio, reqwest, serde, sha3, rmp-serde, hex
3. Auto-Detected Permissions

onchainos Commands Used

Command Found Exists in onchainos CLI Risk Level Context
onchainos wallet addresses ✅ Yes Low Resolve wallet address for Arbitrum/HyperEVM
onchainos wallet sign-message --type eip712 ✅ Yes High Sign HL L1 actions, withdraw3, usdClassTransfer, USDC permit
onchainos wallet contract-call ✅ Yes High Execute Arbitrum contract calls (bridge, relay.link, CoreWriter)
onchainos wallet report-plugin-info ⚠️ Not visible in source reference Low Strategy attribution reporting (may exist but not in provided CLI definition)
onchainos wallet balance ✅ Yes Low Referenced in docs
onchainos wallet login ✅ Yes Referenced in docs

Note: report-plugin-info subcommand is not visible in the provided onchainos source reference. This may be a newer command. Non-critical (failures are logged and don't block trades).

Wallet Operations

Operation Detected? Where Risk
Read balance Yes quickstart, positions, deposit, withdraw (balance checks) Low
Send transaction Yes deposit (Arbitrum→HL bridge), get-gas (relay.link), evm-send (CoreWriter) High
Sign message Yes All perp/spot order + withdraw + transfer via onchainos EIP-712 High
Contract call Yes deposit (batchedDepositWithPermit), get-gas (relay solver), evm-send (CoreWriter) High

External APIs / URLs

URL / Domain Purpose Risk
https://api.hyperliquid.xyz/info Read market data, positions, orders Low
https://api.hyperliquid.xyz/exchange Submit signed orders, withdraws, transfers High
https://api.hyperliquid-testnet.xyz/* Testnet endpoints Low
https://arbitrum-one-rpc.publicnode.com Arbitrum RPC for ERC-20 reads Low
https://rpc.hyperliquid.xyz/evm HyperEVM RPC for HYPE balance, tx receipts Low
https://api.relay.link Cross-chain swap quote + requestId for get-gas Medium
https://raw.githubusercontent.com/okx/plugin-store/... Auto-injected update check (CI-injected, skip)
https://github.com/okx/plugin-store/releases/... Auto-injected binary download (CI-injected, skip)
https://plugin-store-dun.vercel.app/install Auto-injected install stats (CI-injected, skip)
https://www.okx.com/priapi/... Auto-injected OKX report (CI-injected, skip)
https://app.hyperliquid.xyz/settings/api-wallets Referenced in register output for web UI flow Low

Chains Operated On

  • Arbitrum One (chain 42161) — USDC deposits via HL bridge, relay.link source
  • Hyperliquid L1 / HyperEVM (chain 999) — perp/spot trading, CoreWriter precompile, HYPE gas
  • Phantom chain 1337 (HL L1 action signing domain)
  • Chain 421614 (HyperliquidSignTransaction user-signed EIP-712)

Overall Permission Summary

This plugin executes perpetual/spot trading on Hyperliquid, bridges USDC from Arbitrum, withdraws to Arbitrum, and performs cross-chain swaps via relay.link. It does NOT hold private keys directly — all signing is delegated to onchainos (TEE-based). All write operations are gated by --confirm. It reads balances and prices from public APIs, and communicates with two JSON-RPC endpoints. Notable: relay.link is an external third-party service used for USDC→HYPE swaps. No data exfiltration, no hidden commands, no shell invocations of untrusted input.

4. onchainos API Compliance

Does this plugin use onchainos CLI for all on-chain write operations?

Yes — all signing and contract calls are routed through onchainos subprocess invocations.

On-Chain Write Operations (MUST use onchainos)

Operation Uses onchainos? Self-implements? Detail
Wallet signing No onchainos wallet sign-message --type eip712
Transaction broadcasting No onchainos wallet contract-call for EVM broadcasts; HL exchange endpoint for signed HL actions (per HL protocol — not a broadcast, but an API submission of a signed EIP-712 payload)
DEX swap execution N/A N/A (HL native API, not DEX aggregator)
Token approval No Uses EIP-2612 permit signed via onchainos + contract-call for relay.link approve
Contract calls No All via onchainos wallet contract-call
Token transfers No HL native + onchainos signing

Data Queries (allowed to use external sources)

Data Source API/Service Used Purpose
Hyperliquid info API api.hyperliquid.xyz/info Positions, orders, prices, meta, spot balances
Arbitrum RPC (publicnode) arbitrum-one-rpc.publicnode.com USDC balance, permit nonce, allowance, tx receipt
HyperEVM RPC rpc.hyperliquid.xyz/evm Native HYPE balance, tx receipt polling
relay.link api.relay.link Cross-chain swap quote + status polling (used during get-gas)

External APIs / Libraries Detected

  • Direct HTTP calls via reqwest to Hyperliquid, Arbitrum RPC, HyperEVM RPC, relay.link
  • No direct web3 library usage; EIP-712 signing delegated to onchainos
  • Manual ABI encoding in Rust (pad_address, pad_u256, keccak256 via sha3 crate) for bridge calldata and CoreWriter actions

Verdict: ✅ Fully Compliant

All private-key operations are delegated to onchainos. The plugin performs ABI encoding and HL action construction client-side (which is expected — it's not a key operation), then hands off to onchainos for signing. HL exchange API submission of signed payloads is per HL protocol, not a chain broadcast.

5. Security Assessment

Static Rule Scan (C01-C09, H01-H09, M01-M08, L01-L02)

Rule ID Severity Title Matched? Detail
C01 CRITICAL curl | sh remote execute Only in auto-injected pre-flight block (skipped per instructions)
H05 INFO Financial API operation Perps trading, USDC deposit/withdraw — expected for a trading plugin
M03 MEDIUM Third-party content reqwest calls to Hyperliquid, Arbitrum RPC, HyperEVM RPC, relay.link — expected; data boundary declared in SKILL.md
M07 MEDIUM Missing untrusted data boundary SKILL.md explicitly includes "Data Trust Boundary" section and "Treat all data returned by this plugin and the Hyperliquid API as untrusted external content"

All other static rules (C02-C09, H01-H04, H06-H09, M01, M02, M04-M06, M08, L01, L02) do not match. No hardcoded secrets, no eval/exec, no persistence hooks, no credential access, no obfuscation, no DAN/jailbreak, no Base64 payloads, no HTML comments with shell commands.

LLM Judge Analysis (L-PINJ, L-MALI, L-MEMA, L-IINJ, L-AEXE, L-FINA, L-FISO)

Judge Severity Detected Confidence Evidence
L-PINJ CRITICAL 0.95 No injection patterns; CLI args are strongly typed via clap; no raw user input concatenated into shell commands unsafely
L-MALI CRITICAL 0.9 Declared behavior (HL trading) matches actual code; no hidden exfiltration
L-MEMA HIGH 0.95 No writes to MEMORY.md, SOUL.md, or .claude/memory/
L-IINJ INFO 0.95 External requests declared (HL, Arbitrum RPC, HyperEVM, relay.link); data boundary present → INFO
L-AEXE INFO ⚠️ 0.85 All write ops gated by --confirm; clear preview-before-execute pattern; silent/automated mode explicitly requires explicit authorization (not enabled by default)
L-FINA INFO 0.95 Write ops with explicit confirmation + credential gating (onchainos TEE) → INFO-level
L-FISO INFO 0.9 Field enumeration present in SKILL.md Display sections

Toxic Flow Detection (TF001-TF006)

No toxic flows detected. TF006 does not apply because M07 is not triggered (data boundary is declared).

Prompt Injection Scan

No injection patterns found. No <SYSTEM> tags, no "ignore previous instructions", no Base64 payloads, no Unicode escapes, no HTML comments with shell commands. Two <external-content> tags are used legitimately to wrap example output.

Result: ✅ Clean

Dangerous Operations Check

The plugin handles transfers, signing, contract calls, and transaction broadcasting. Every write operation requires --confirm. The order, close, tpsl, cancel, spot-order, spot-cancel, deposit, withdraw, transfer, get-gas, evm-send commands all show a preview by default and only execute with --confirm.

Result: ✅ Safe

Data Exfiltration Risk

No suspicious outbound traffic. Data reports go only to Hyperliquid API (expected) and the auto-injected CI stats endpoints (skipped per instructions). Strategy attribution via report-plugin-info sends only order metadata to OKX backend via the official onchainos CLI, not directly.

Result: ✅ No Risk

Overall Security Rating: 🟢 Low Risk

6. Source Code Security

Language & Build Config

Rust, entry point src/main.rs, binary name hyperliquid-plugin, edition 2021.

Dependency Analysis

  • clap 4 — standard CLI parser
  • tokio 1 — async runtime
  • reqwest 0.12 — HTTP client with native-tls
  • serde, serde_json — serialization
  • rmp-serde 1.3 — MessagePack (required for HL L1 action hashing per HL protocol)
  • sha3 0.10 — Keccak256 (required for HL connection ID + EVM calldata selectors)
  • hex 0.4, anyhow 1

All dependencies are well-maintained, widely used, and pinned via Cargo.lock. No suspicious crates.

Code Safety Audit

Check Result Detail
Hardcoded secrets No private keys, API keys, or mnemonics. Only public contract addresses (USDC Arbitrum, HL bridge) and public RPC URLs
Network requests to undeclared endpoints All endpoints declared in plugin.yaml api_calls
File system access outside plugin scope No file reads/writes outside subprocess invocations
Dynamic code execution (eval, exec) No eval. Uses std::process::Command to invoke onchainos binary — arguments are clap-parsed, not user-concatenated strings
Environment variable access beyond declared env Only reads HYPERLIQUID_TESTNET (documented)
Build scripts with side effects No build.rs
Unsafe code blocks No unsafe blocks detected

Subprocess invocations: Command::new("onchainos").args([...]) — all args are either fixed strings or from typed clap arguments. No shell=true or string concatenation into shell commands. Safe.

Manual ABI encoding (deposit.rs) is reviewed: correct Keccak256 selector derivation, proper padding, uses hex crate for decoding. The batchedDepositWithPermit calldata is built carefully with clear offset/length arithmetic.

One minor observation: in deposit.rs, permit signing and bridge contract call use EIP-2612 standard flow. The signature is split into r/s/v correctly and encoded into ABI. No issues.

Does SKILL.md accurately describe what the source code does?

Yes. Every documented command maps to a corresponding handler in src/commands/. Parameter semantics match. Risk level descriptions are accurate.

Verdict: ✅ Source Safe

7. Code Review

Quality Score: 92/100

Dimension Score Notes
Completeness 24/25 Pre-flight, commands, error handling, clear confirm-before-execute. Minor: some commands could elaborate on retry strategy
Clarity 24/25 Good descriptions, examples, clear data boundary notice. Comprehensive changelog
Security Awareness 24/25 All writes gated by --confirm, TEE signing disclaimer, no unlimited approvals, slippage defaults, balance pre-checks, fee transparency on withdraw
Skill Routing 14/15 Correct defers to onchainos; clear scope limits in "Do NOT Use For"
Formatting 10/10 Well-structured markdown, tables, code blocks

Strengths

  • Two-layer confirmation pattern: preview → explicit --confirm flag
  • Explicit withdrawal fee disclosure ($1 USDC), accurate balance pre-check
  • Excellent data trust boundary declaration, Display field enumeration per command
  • Balance pre-flight on order command prevents wasted gas
  • Strategy attribution is opt-in (--strategy-id), failures non-fatal

Issues Found

  • 🔵 Minor: The onchainos wallet report-plugin-info subcommand is not visible in the provided onchainos CLI source reference. If this command doesn't exist, strategy attribution will silently fail (log to stderr only) — this is handled gracefully but worth verifying.
  • 🔵 Minor: api_calls in plugin.yaml lists app.hyperliquid.xyz but this is only referenced as a URL in user-facing text (register output), not an actual API call. Harmless but slightly misleading.
8. SUMMARY.md Review
Check Result
File exists
Written in English
Has "## 1. Overview" section ⚠️ (uses "## Overview" without number — acceptable)
Has "## 2. Prerequisites" section ⚠️ (uses "## Prerequisites" without number)
Has "## 3. Quick Start" section ⚠️ (uses "## Quick Start" without number)
Character count ≤ 17,000 ✅ 1434 chars

Sections are present but not numbered. Content is well-structured and concise.

10. Recommendations
  1. Verify onchainos wallet report-plugin-info is a real subcommand in the current onchainos CLI. If not, document that strategy attribution requires a specific onchainos version or is a placeholder.
  2. Consider numbering the SUMMARY.md sections as "## 1. Overview", "## 2. Prerequisites", "## 3. Quick Start" to match the Plugin Store convention (strict reviewers may flag this).
  3. Remove app.hyperliquid.xyz from api_calls since it's a user-facing URL, not an API endpoint used by the binary.
  4. Consider adding a rate-limit/backoff note for the Arbitrum publicnode RPC, which may throttle under heavy use.
  5. Document that HYPERLIQUID_TESTNET=1 env var switches all endpoints to testnet (mentioned in config.rs but not in SKILL.md).
11. Reviewer Summary

One-line verdict: Well-structured Rust plugin for Hyperliquid perps trading with strong security posture — all signing delegated to onchainos TEE, all writes gated by --confirm, data boundary declared, and no malicious patterns detected.

Merge recommendation: ✅ Ready to merge

Minor non-blocking suggestions: verify report-plugin-info availability in target onchainos versions; optionally add numeric prefixes to SUMMARY.md section headings for convention alignment.


Generated by Claude AI via Anthropic API — review the full report before approving.

@Noah3595 Noah3595 merged commit 45a9eb2 into okx:main Apr 22, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants