Sign and Broadcast Transaction
To sign and broadcast a transaction to the Hyperliquid network, follow these steps:
- Retrieve an 
unsignedTransactionobject from the relevant API endpoint, e.g.,/staking/transfer,/staking/delegate,/staking/undelegate,/staking/withdraw. - Sign the transaction using the following code:
import { signUserSignedAction, userSignedActionEip712Types, isValidPrivateKey } from "@nktkas/hyperliquid/signing"; async function signTransaction(privateKey, unsignedTransaction) { const action = unsignedTransaction.action; return Buffer.from( JSON.stringify({ ...unsignedTransaction, signature: await signUserSignedAction({ wallet: privateKey, action: action, types: userSignedActionEip712Types[action.type], }), }) ).toString("base64"); } (async () => { const [, , rawTransaction, privateKey] = process.argv; if (!rawTransaction || typeof rawTransaction !== "string") { console.error("Invalid raw transaction. It should be a base64-encoded string."); process.exit(1); } if (!privateKey || typeof privateKey !== "string" || !isValidPrivateKey(privateKey)) { console.error("Invalid private key."); process.exit(1); } const unsignedTransaction = JSON.parse(Buffer.from(rawTransaction, "base64").toString("utf-8")); if ( !("action" in unsignedTransaction) || !("type" in unsignedTransaction.action) || !["cDeposit", "tokenDelegate", "cWithdraw"].includes(unsignedTransaction.action.type) ) { console.error("Invalid unsigned transaction."); process.exit(1); } console.log(await signTransaction(privateKey.startsWith("0x") ? privateKey : `0x${privateKey}`, unsignedTransaction)); })(); /** * To run with env variables: * * $ export RAW_TX= 'rawtxhere' * $ export PRIVATE_KEY= 'privatekeyhere' * $ npx --yes -p @nktkas/[email protected] node hyperliquid-signer.js $RAW_TX $PRIVATE_KEY **/ - Broadcast the signed transaction to the Hyperliquid network by sending a POST request to /api/v1/hyperliquid/[network]/transaction/send endpoint.
 
Example request (for testnet network):
curl --request POST \
     --url https://api-test.p2p.org/api/v1/hyperliquid/testnet/transaction/send \
     --header 'accept: application/json' \
     --header 'authorization: Bearer <token>' \
     --header 'content-type: application/json' \
     --data '
{
  "signedTransaction": "string"
}
'signedTransaction— signed transaction in the hexadecimal format which needs to be broadcasted to the network.
Example response:
{
  "result": {
    "createdAt": "2025-10-10T05:28:10.434Z",
    "network": "mainnet"
  },
  "error": {}
}createdAt— timestamp of the transaction in the ISO 8601 format.network— network name.
What's Next?
- Staking API reference
 
Updated 25 days ago