Skip to content

Commit 2b08318

Browse files
guibvieiraclaude
andcommitted
docs: record Hyperliquid multisig protocol gotchas in CLAUDE.md
Documents the signature trimming root cause and other hard-won lessons so future agents don't repeat weeks of debugging. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 412afb7 commit 2b08318

1 file changed

Lines changed: 24 additions & 0 deletions

File tree

CLAUDE.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,30 @@ Use Chrome remote debugging MCP only when you specifically need to attach to an
111111

112112
Does not work properly yet.
113113

114+
## Hyperliquid protocol gotchas
115+
116+
Hard-won lessons about the Hyperliquid multisig wire protocol. Violating any of these produces opaque errors.
117+
118+
**Signature trimming (outer action hash)**
119+
120+
The server strips leading zeros from inner signature `r` and `s` values before recomputing the `multiSig` action hash to verify the outer signer. You must do the same — trim before hashing, and send the trimmed values in the POST body. Sending raw (untrimmed) signatures causes the server's hash to diverge from yours, the outer sig recovers to the wrong address, and the server returns `"Invalid multi-sig outer signer"` with no further detail. This error message is misleading — the signer address and key are correct; only the hash input differs. See `trimSignature()` in `src/lib/execute.ts` and `trim_sig()` in `submit_multisig.py`.
121+
122+
**Outer nonce must match inner action nonce**
123+
124+
The top-level POST `nonce` and the `SendMultiSig` EIP-712 message `nonce` must be identical to the nonce field inside the inner action. Using `Date.now()` at submission time produces a mismatch; the server returns `"Nonce mismatch"`.
125+
126+
**Agent name length**
127+
128+
`approveAgent` enforces a 1–16 character limit on `agentName`. The server returns `"Extra agent name must be between 1 and 16 characters long"`.
129+
130+
**Nonce must be monotonically increasing**
131+
132+
Reusing or replaying a nonce lower than the last accepted one returns `"Invalid nonce: nonce too low"`. Always use a fresh timestamp after a failed submission.
133+
134+
**EIP712Domain must be explicit**
135+
136+
Rabby (and MetaMask internally via `@metamask/eth-sig-util`) computes a different domain separator when `EIP712Domain` is omitted from the `types` object. Always include it explicitly in both inner and outer `eth_signTypedData_v4` calls.
137+
114138
## Pull requests
115139

116140
- Pull request description must have sections Why (the rational of change), Lessons learnt (memory for future agents) and Summary (what was changed). No test plan or verification section.

0 commit comments

Comments
 (0)