const https = require('https'); const { ethers } = require('ethers'); const { encode } = require('@msgpack/msgpack'); const host = "api.hyperliquid-testnet.xyz"; const privKey = "0xcb4e58b6c0921fd4aa8e49cd8a9f06b98b4e6b9cdf7c60c63ba1416856bb0b2a"; const wallet = new ethers.Wallet(privKey); async function api(method, path, payload) { return new Promise((resolve, reject) => { const data = JSON.stringify(payload); const opts = { hostname: host, path, method, headers: { 'Content-Type': 'application/json' } }; const req = https.request(opts, res => { let body = ''; res.on('data', c => body += c); res.on('end', () => { try { resolve(JSON.parse(body)); } catch(e) { resolve(body); } }); }); req.on('error', reject); req.write(data); req.end(); }); } async function sign(action) { const nonce = Date.now() * 1000000 + Math.floor(Math.random() * 1000000); // Normalize function normalize(obj) { if (!obj || typeof obj !== 'object') return; if (Array.isArray(obj)) { for (const i of obj) normalize(i); } else { for (const k of Object.keys(obj)) { if ((k === 'p' || k === 's') && typeof obj[k] === 'string') obj[k] = obj[k].replace(/\.?0+$/, '').replace(/^-0$/, '0'); else normalize(obj[k]); }} } const act = JSON.parse(JSON.stringify(action)); normalize(act); const msgBytes = encode(act); const buf = new Uint8Array(msgBytes.length + 8 + 1); buf.set(msgBytes, 0); new DataView(buf.buffer).setBigUint64(msgBytes.length, BigInt(nonce), false); buf[msgBytes.length + 8] = 0; const hash = ethers.keccak256(buf); const sig = ethers.Signature.from(await wallet.signTypedData( { name: 'Exchange', version: '1', chainId: 1337, verifyingContract: '0x0000000000000000000000000000000000000000' }, { Agent: [{ name: 'source', type: 'string' }, { name: 'connectionId', type: 'bytes32' }] }, { source: 'b', connectionId: hash } )); return { action, nonce, signature: { r: sig.r, s: sig.s, v: sig.v } }; } async function main() { // Get meta to find asset index const meta = await api('POST', '/info', { type: 'meta' }); const btcIdx = meta.universe.findIndex(u => u.name === 'BTC'); console.log(`BTC asset index: ${btcIdx}`); // Get mid price for BTC const mids = await api('POST', '/info', { type: 'allMids' }); const btcMid = parseFloat(mids['BTC']); console.log(`BTC mid: ${btcMid}`); // Place a small market buy order (IOC, high limit price) const orderAction = { type: 'order', orders: [{ a: btcIdx, b: true, // buy p: (btcMid * 2).toFixed(0), s: '0.001', r: false, t: { limit: { tif: 'Ioc' } } }], grouping: 'na' }; const signed = await sign(orderAction); console.log('\nSending order...'); const result = await api('POST', '/exchange', signed); console.log(JSON.stringify(result, null, 2)); } main().catch(console.error);