Skip to main content
Withdraw USDC from a HyperCore spot or perp balance directly to a Solana associated token account (ATA) using CCTP. The withdrawal burns USDC on HyperEVM and mints it on Solana in a single operation. For withdrawals to EVM blockchains, see Withdraw USDC from HyperCore to EVM chains. For CCTP domain IDs, see Supported blockchains and domains.

Prerequisites

Before you begin, ensure that you’ve:
  • Installed Node.js v22+
  • Prepared an EVM wallet with the private key available
  • Funded your HyperCore account with USDC in either spot or perp balance
  • Created a new Node project and installed dependencies:
  • Created a .env file with required environment variables. Open the file in your editor and add your private key and Solana addresses:
    Keep your private key safe and never commit .env to version control. Add .env to your .gitignore file.
Withdrawals also include a HyperCore fee, and when createATA hook data is included in the data field, an additional CCTP forwarding fee is added. If the withdrawal amount is less than the HyperCore and CCTP forwarding fees combined, the transaction reverts on HyperEVM.

Steps

Step 1. Derive the recipient ATA and createATA hook data

For Solana, the mint recipient is the associated token account for the USDC mint and recipient owner. The createATA hook data tells CCTP to create that ATA when needed.
TypeScript

Step 2. Construct the sendToEvmWithData action

Create a sendToEvmWithData action object with the following parameters:
  • type: sendToEvmWithData
  • hyperliquidChain: Mainnet (or Testnet for testnet)
  • signatureChainId: The ID of the chain used when signing in hexadecimal format (for example, "0xa4b1" for Arbitrum).
  • token: USDC
  • amount: The amount of USDC as a string (for example, "10" for 10 USDC, "1.5" for 1.5 USDC)
  • sourceDex: "spot" to withdraw from spot balance, or "" for perp balance
  • destinationRecipient: The recipient ATA on Solana. This is the ATA for the recipient owner and the USDC mint, not the owner wallet address.
  • addressEncoding: base58 for Solana recipients
  • destinationChainId: 5, the CCTP destination domain ID for Solana
  • gasLimit: Gas limit for the transaction on the destination blockchain
  • data: The createATA hook data from the previous step, which includes the recipient owner public key as ataOwner. The CCTP destinationCaller is always set to the zero address, so any caller can submit the CCTP receive instruction on Solana. The USDC still mints only to destinationRecipient.
  • nonce: Current timestamp in milliseconds
TypeScript

Step 3. Sign the action using EIP-712

Sign the action using the EIP-712 typed data signing standard. The signature proves that you authorize this withdrawal. The signing domain should include:
  • name: "HyperliquidSignTransaction"
  • version: "1"
  • chainId: The chain ID from signatureChainId (as a number)
  • verifyingContract: "0x0000000000000000000000000000000000000000"
TypeScript

Step 4. Submit the signed action to the exchange API

Call the exchange endpoint with the action, nonce, and signature.
TypeScript

Full example code

The following is a complete example of how to withdraw USDC from HyperCore to Solana. By default, it withdraws 10 USDC from your perp balance. Update destinationChainId only if the CCTP Solana domain changes, and set signatureChainId to the ID of the chain used when signing in hexadecimal format.
TypeScript
Run the script: