Skip to main content
Transfers route USDC between Hyperliquid, Lighter, and your Arbitrum wallet. The endpoint you start with depends on where the funds are leaving from:
Prerequisites: an active VOOI API token and the source venue connected. See API Tokens and Use your own keys if you don’t have them yet.

Supported routes

Every other venue — Aster, Extended, Robinhood, Binance, Bybit, MEXC, and Ondo — is neither a supported source nor destination for transfers. Use Deposits to fund them and Withdrawals to take funds out, or Extended withdrawals for Extended. Binance, Bybit, and MEXC expose no deposits or withdrawals through VOOI at all — move funds through those venues directly.

From Hyperliquid or Lighter

1. Prepare

By default funds go to your own registered wallet — the address VOOI has on file for you. To send to a different wallet — for example, paying out an Arbitrum withdrawal to an address other than the registered one — include address. The response’s transferDataToSign is shaped by source (see step 2), and it always includes a quoteDataToSign you must also sign — on every transfer, including ones going to your own registered wallet. Full schema lives in the API reference. Fees. fee and exchangeFee are both USDC decimal values. fee is the total deducted from the transfer: your source balance drops by the amount you requested, and the destination receives amount − fee. exchangeFee is the portion of fee retained by the source venue — it’s already included in fee, not added on top. The remainder, fee − exchangeFee, is the routing fee.

2. Sign

The shape of transferDataToSign depends on source:

Source: Hyperliquid

An EIP-712 envelope for Hyperliquid’s usdSend action:
time is the only uint64 field — encode it as an unsigned 64-bit integer before signing:

Source: Lighter

A plain-text string. Sign it as a plain personal-sign message, not as EIP-712 typed data:

Sign the quote

prepare always returns a quoteDataToSign — an EIP-712 envelope authorizing the transfer quote on the destination side. Sign it in addition to transferDataToSign:

3. Submit

Post both signatures back. quoteSignature is required on every transfer — omitting it returns a 400.
VOOI submits the signed payload to the source venue on your behalf — you don’t broadcast it yourself.

From your Arbitrum wallet

address here is the source wallet (the one your signer controls) — opposite role from the address field on /transfer/prepare. exchange is the destination, hyperliquid or lighter. The response carries transferId, fee, and ready-to-broadcast calldata:
data is ERC-20 transfer() calldata with a short reference suffix appended — VOOI uses the suffix to match the on-chain transaction back to this transferId. Submit the transaction as-is; don’t modify or truncate data, and don’t call /transfer/execute.
You pay Arbitrum gas in ETH separately.

Status and retry

Transfers move through created → pending → sent → paid → confirmed, or land on failed / refunded. Poll GET /transfer/status with the transferId to follow the progression; GET /transfer/history paginates the same records. transferId is single-use. If the execute call times out, retry with the same transferId and signatures — the status endpoint is authoritative for the final outcome. Only prepare a new transfer after confirming the previous one failed. A Hyperliquid or Lighter transfer that stays in created for more than 24 hours — meaning it was never executed — moves to failed. For an Arbitrum-wallet transfer, re-broadcasting the same signed transaction is a no-op once it has been mined; on network errors, query the status endpoint rather than starting over.

Next steps

Deposit into an exchange

Fund a venue from an external wallet

Start trading

Place your first order