We build custom applications 5x faster and cheaper 🚀
Book a Free Consultation
Stuck on an error? Book a 30-minute call with an engineer and get a direct fix + next steps. No pressure, no commitment.
Direct answer: Build a small, explicit OpenClaw skill that calls Hyperliquid’s REST APIs (or uses Hyperliquid OAuth flows), store credentials securely via ClawHub’s secret/environment configuration, host any webhook receivers and long-running or stateful work in an external service (web server + database), and wire the skill to invoke that service. Authenticate every API call, verify webhook signatures, handle token refresh and retries outside the agent runtime, and use logs and HTTP responses to debug. The integration is an explicit set of API calls, secrets, and webhooks — not magic — so design around clear authentication, scope limits, monitoring, and moving stateful components out of the agent runtime for reliability.
// Example webhook receiver (Node.js + Express)
// It expects the vendor to send an HMAC header named 'x-hl-signature' (placeholder).
// Replace header name and HMAC algorithm with values from Hyperliquid docs.
const express = require('express');
const crypto = require('crypto');
const app = express();
// Use raw body so HMAC is computed on the exact bytes received
app.use(express.raw({ type: '*/*' }));
app.post('/webhook', (req, res) => {
const signature = req.headers['x-hl-signature']; // <b>//</b> adjust header name to vendor docs
const secret = process.env.HL_WEBHOOK_SECRET; // <b>//</b> set in ClawHub secrets
if (!signature || !secret) {
return res.status(401).send('unauthorized');
}
// <b>//</b> compute HMAC exactly as vendor requires (sha256 shown as common example)
const computed = crypto.createHmac('sha256', secret).update(req.body).digest('hex');
// <b>//</b> use timingSafeEqual to avoid timing attacks
try {
const valid = crypto.timingSafeEqual(Buffer.from(computed), Buffer.from(signature));
if (!valid) {
return res.status(401).send('invalid signature');
}
} catch (err) {
return res.status(401).send('invalid signature format');
}
const payload = JSON.parse(req.body.toString());
// <b>//</b> enqueue or process the payload (store to DB, notify downstream systems)
console.log('webhook payload', payload);
res.sendStatus(200);
});
const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`webhook listener on ${port}`));
// HTTP call to vendor API using an API key
// Replace URL, endpoint and JSON fields with vendor-specific values.
const fetch = require('node-fetch');
async function placeOrder(order) {
const url = 'https://api.hyperliquid.example/v1/orders'; // <b>//</b> placeholder
const resp = await fetch(url, {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.HL_API_KEY}`, // <b>//</b> stored in ClawHub secrets
'Content-Type': 'application/json'
},
body: JSON.stringify(order)
});
if (!resp.ok) {
const text = await resp.text();
// <b>//</b> inspect status and body for vendor errors
throw new Error(`Hyperliquid API error ${resp.status}: ${text}`);
}
return resp.json();
}
// <b>//</b> example usage
placeOrder({ symbol: 'BTCUSD', side: 'buy', size: 0.01 })
.then(r => console.log('order placed', r))
.catch(e => console.error('order failed', e));
// Generic OAuth2 token refresh using client credentials + refresh token
// Replace tokenUrl and parameters with vendor-provided endpoints and names.
const fetch = require('node-fetch');
async function refreshAccessToken(refreshToken) {
const tokenUrl = 'https://auth.hyperliquid.example/oauth/token'; // <b>//</b> placeholder
const params = new URLSearchParams();
params.append('grant_type', 'refresh_token');
params.append('refresh_token', refreshToken);
params.append('client_id', process.env.HL_CLIENT_ID);
params.append('client_secret', process.env.HL_CLIENT_SECRET);
const res = await fetch(tokenUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: params
});
if (!res.ok) {
const body = await res.text();
throw new Error(`token refresh failed ${res.status}: ${body}`);
}
return res.json(); // <b>//</b> contains new access_token (+ maybe new refresh_token)
}
Speak one‑on‑one with a senior engineer about your no‑code app, migration goals, and budget. In just half an hour you’ll leave with clear, actionable next steps—no strings attached.
1
Direct answer: The 401 happens because Hyperliquid’s WebSocket handshake requires a freshly computed HMAC (usually including a timestamp/nonce and the connect path/payload) but the ClawConnector configured via claw_config.yaml only provides static keys — it does not automatically compute or inject the dynamic signature into the WS handshake. The server therefore rejects an unsigned/incorrectly-signed connect.
The handshake must carry a valid, time‑bound signature. Common causes:
Compute the HMAC at connect time and include it in the WS handshake (header or query param per Hyperliquid docs). Example (Node.js):
```js // compute signature and attach to websocket headers const crypto = require('crypto'); const sig = crypto.createHmac('sha256', secret).update(`${ts}${method}${path}`).digest('hex'); const ws = new WebSocket(url, { headers: { 'X-API-KEY': key, 'X-SIGNATURE': sig, 'X-TIMESTAMP': ts } }); ```2
ClawOrderBook drops Hyperliquid level2 deltas when the snapshot sequence number and the incoming incremental update sequence don’t line up, because applying out‑of‑order or gapped deltas would corrupt the local book. The implementation rejects unsafe deltas and forces a resync (fresh snapshot + aligned seq) rather than risking inconsistent state.
This is a safety-first design: level2 deltas assume a precise sequence when they are applied. If there’s a gap, overlap, or mismatch you must:
3
Direct answer: Incorrect mapping usually comes from interpreting Hyperliquid's execution report fields incorrectly — using last-fill instead of cumulative-filled, misreading status enums, or letting tiny rounding remainders keep an order as PARTIAL_FILL; combined with out-of-order or missing events this produces reconciliation mismatches.
4
Direct answer: ClawRiskModule rejects orders because it enforces that quantities and prices match the symbol rules (lot size/step and tick size/decimals) stored in ClawSymbolTable; if those configured values differ from Hyperliquid’s live symbol metadata the module flags a mismatch as InvalidLotSize or InvalidTickSize.
ClawRiskModule validates that order quantity is an integer multiple of the symbol’s lot step and that price aligns to the tick. Mismatched decimals or steps cause rounding/precision differences so the check fails.
// Quantize price/qty to exchange rules
function quantize(value, step){
// return nearest multiple of step
return Math.round(value / step) * step;
}
// // use integer scaling if needed to avoid float errors
This prompt helps an AI assistant understand your setup and guide you through the fix step by step, without assuming technical knowledge.
From startups to enterprises and everything in between, see for yourself our incredible impact.
Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We’ll discuss your project and provide a custom quote at no cost.Â