Socket supports swapping assets from any EVM chain to HyperCore and from HyperCore to any EVM chain.
This guide walks you through swapping assets between EVM chains and HyperCore using Socket, including transaction options and current limitations.
Quick Start
Key differences
Follow the “Auto routing” guides when going from any EVM to HyperCore. The main differences when integrating HyperCore compared to standard EVM chains:
Transaction Flow from HyperCore to EVM
User sends funds to a Deposit contract with the quote ID
Socket indexes the transaction and delivers the funds on the destination chain
API Behavior
Both userAddress and receiverAddress required for quotes
The only assets supported from/to HyperCore are USDC (Spot) and USDC (Perps)
There is no Fee collection currently from HyperCore to EVM
Quote responses already account for HyperCore’s 1 USDC activation fee for new account activations and withdrawals
Only USDC (Perps) is supported when bridging out of Hypercore
The inputAmount parameter must be provided as an integer string in 6-decimal base units (micro-units) :
Human-readable inputAmount value9.99 USDC "9990000"2.00 USDC "2000000"10.23 USDC "10230000"
Conversion formula: inputAmount = humanAmount × 10^6 (rounded to integer)
Integration Steps
HyperCore to EVM
Select Chains: Choose source and destination chains.
Fetch Routes: Retrieve the deposit route using the /quote endpoint. The response contains depositRoute.signTypedData and depositRoute.quoteId.
Sign and Submit: Sign the signTypedData with primaryType: "HyperCoreTransaction:SendAsset", then submit the signed data to HyperLiquid’s API endpoint (https://api.hyperliquid.xyz/exchange).
Track Transaction Status: Poll the /status endpoint using the quoteId until the bridging process is complete.
For HyperCore quotes, ensure both userAddress and receiverAddress are defined. HyperCore to EVM is under depositRoute (not autoRoute).
Examples
Queries
Quote from Optimism USDC to HyperCore USDC (Spot)
https://public-backend.bungee.exchange/api/v1/bungee/quote?userAddress=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045&receiverAddress=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045&originChainId=10&destinationChainId=1337&inputToken=0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85&outputToken=0x2000000000000000000000000000000000000000&inputAmount=2000000
Quote from HyperCore USDC (Perps) to Optimism USDC
https://public-backend.bungee.exchange/api/v1/bungee/quote?userAddress=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045&receiverAddress=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045&originChainId=1337&destinationChainId=10&inputToken=0x6d1e7cde53ba9467b783cb7c530ce054&outputToken=0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85&inputAmount=10230000
Scripts
Quote and swap from Optimism USDC to HyperCore USDC (Spot)
import { privateKeyToAccount } from "viem/accounts" ;
import { createPublicClient , http , createWalletClient } from "viem" ;
import { optimism } from "viem/chains" ;
if ( ! process . env . PRIVATE_KEY ) {
console . error ( "Error: PRIVATE_KEY environment variable is not set" );
process . exit ( 1 );
}
const account = privateKeyToAccount (
process . env . PRIVATE_KEY . startsWith ( '0x' )
? process . env . PRIVATE_KEY
: `0x ${ process . env . PRIVATE_KEY } `
);
const publicClient = createPublicClient ({ chain: optimism , transport: http () });
const walletClient = createWalletClient ({ account , chain: optimism , transport: http () });
const BUNGEE_API_BASE_URL = "https://public-backend.bungee.exchange" ;
const quoteParams = {
userAddress: account . address ,
receiverAddress: account . address ,
originChainId: 10 , // Optimism
destinationChainId: 1337 , // HyperCore
inputToken: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85" , // USDC on Optimism
outputToken: "0x2000000000000000000000000000000000000000" , // USDC (SPOT) on HyperCore
inputAmount: "2000000" , // 2 USDC
};
async function getQuote ( params ) {
const url = ` ${ BUNGEE_API_BASE_URL } /api/v1/bungee/quote? ${ new URLSearchParams ( params ) } ` ;
const response = await fetch ( url );
const data = await response . json ();
if ( ! data . success || ! data . result . autoRoute ) {
throw new Error ( `Quote failed: ${ data . message } ` );
}
return {
quoteId: data . result . autoRoute . quoteId ,
requestType: data . result . autoRoute . requestType ,
signTypedData: data . result . autoRoute . signTypedData ,
approvalData: data . result . autoRoute . approvalData ,
};
}
async function main () {
console . log ( "Getting quote..." );
const quote = await getQuote ( quoteParams );
console . log ( "Quote ID:" , quote . quoteId );
console . log ( "Request Type:" , quote . requestType );
// Sign the typed data with primaryType: "PermitWitnessTransferFrom"
// Submit to /api/v1/bungee/submit and poll /status with requestHash
}
main ();
Quote and swap from HyperCore USDC (Perps) to Optimism USDC
import { privateKeyToAccount } from "viem/accounts" ;
import { http , createWalletClient , parseSignature } from "viem" ;
import { arbitrum } from "viem/chains" ;
if ( ! process . env . PRIVATE_KEY ) {
process . exit ( 1 );
}
const normalizedKey = process . env . PRIVATE_KEY . trim (). startsWith ( '0x' )
? process . env . PRIVATE_KEY . trim ()
: `0x ${ process . env . PRIVATE_KEY . trim () } ` ;
const account = privateKeyToAccount ( normalizedKey );
const walletClient = createWalletClient ({ account , chain: arbitrum , transport: http () });
const BUNGEE_API_BASE_URL = "https://public-backend.bungee.exchange" ;
const HYPERLIQUID_API_URL = "https://api.hyperliquid.xyz/exchange" ;
const quoteParams = {
userAddress: account . address ,
receiverAddress: account . address ,
originChainId: 1337 , // HyperCore
destinationChainId: 10 , // Optimism
inputToken: "0x6d1e7cde53ba9467b783cb7c530ce054" , // USDC (Perps)
outputToken: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85" , // USDC on Optimism
inputAmount: "10230000" ,
};
async function main () {
const url = ` ${ BUNGEE_API_BASE_URL } /api/v1/bungee/quote? ${ new URLSearchParams ( quoteParams ) } ` ;
const response = await fetch ( url );
const data = await response . json ();
if ( ! data . success || ! data . result . depositRoute ) {
throw new Error ( `Quote failed: ${ data . message } ` );
}
const { quoteId , signTypedData } = data . result . depositRoute ;
// Sign with primaryType: "HyperCoreTransaction:SendAsset"
const signature = await walletClient . signTypedData ({
types: signTypedData . types ,
primaryType: "HyperCoreTransaction:SendAsset" ,
message: signTypedData . values ,
domain: signTypedData . domain ,
});
const { r , s , v } = parseSignature ( signature );
// Submit to HyperLiquid API
await fetch ( HYPERLIQUID_API_URL , {
method: "POST" ,
headers: { "Content-Type" : "application/json" },
body: JSON . stringify ({
action: signTypedData . values ,
nonce: signTypedData . values . nonce ,
signature: { r , s , v: Number ( v ) },
}),
});
// Poll /status with quoteId
console . log ( "Quote ID:" , quoteId );
}
main ();