Skip to main content

Quick Start

This guide walks you through bridging assets from any supported chain to Hyperliquid using the Mina SDK. By the end, you will have executed a complete cross-chain bridge with automatic deposit to your trading account.

Prerequisites

Before you begin, ensure you have:
Install the Mina SDK and its peer dependency:
npm install @siphoyawe/mina-sdk viem
  • An EVM wallet with tokens you want to bridge
  • Sufficient native token (ETH, MATIC, etc.) for gas fees

Step 1: Initialize the SDK

Create a new Mina instance with your configuration. The integrator field is required and identifies your application.
import { Mina } from '@siphoyawe/mina-sdk';

// Initialize the SDK
const mina = new Mina({
  integrator: 'my-app',      // Your app identifier
  autoDeposit: true,          // Auto-deposit to Hyperliquid L1
  defaultSlippage: 0.005      // 0.5% slippage tolerance
});
The autoDeposit option ensures bridged USDC is automatically deposited to your Hyperliquid L1 trading account. Set to false if you want USDC to remain on HyperEVM.

Step 2: Discover Chains

Fetch the list of supported source chains. The SDK supports 40+ chains that can bridge to HyperEVM.
// Get all supported chains
const { chains } = await mina.getChains();

console.log(`Found ${chains.length} supported chains`);

// Find a specific chain (e.g., Arbitrum)
const arbitrum = chains.find(chain => chain.id === 42161);
console.log(`Arbitrum: ${arbitrum?.name}`);
Example Response:
{
  chains: [
    { id: 1, name: 'Ethereum', nativeToken: { symbol: 'ETH', ... } },
    { id: 42161, name: 'Arbitrum', nativeToken: { symbol: 'ETH', ... } },
    { id: 10, name: 'Optimism', nativeToken: { symbol: 'ETH', ... } },
    // ... 40+ more chains
  ]
}

Step 3: Get Tokens

Fetch the tokens available for bridging on your source chain.
// Get tokens available on Arbitrum (chain ID: 42161)
const { tokens } = await mina.getTokens(42161);

console.log(`Found ${tokens.length} bridgeable tokens on Arbitrum`);

// Find USDC on Arbitrum
const usdc = tokens.find(token => token.symbol === 'USDC');
console.log(`USDC address: ${usdc?.address}`);
Common token addresses on Arbitrum:
  • USDC: 0xaf88d065e77c8cC2239327C5EDb3A432268e5831
  • USDC.e (Bridged): 0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8

Step 4: Get a Quote

Request a bridge quote specifying the source chain, tokens, and amount.
// Get a quote to bridge 100 USDC from Arbitrum to HyperEVM
const quote = await mina.getQuote({
  fromChain: 42161,                                          // Arbitrum
  toChain: 999,                                              // HyperEVM
  fromToken: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',   // USDC on Arbitrum
  toToken: '0x0000000000000000000000000000000000000000',     // Native representation
  amount: '100000000',                                       // 100 USDC (6 decimals)
  fromAddress: '0xYourWalletAddress'                         // Your wallet address
});

console.log('Quote received:');
console.log(`  From: ${quote.fromAmount} ${quote.fromToken.symbol}`);
console.log(`  To: ${quote.toAmount} ${quote.toToken.symbol}`);
console.log(`  Estimated time: ${quote.estimatedTime}s`);
console.log(`  Gas cost: $${quote.gasCostUSD}`);
Quote Response Structure:
{
  id: 'quote_abc123',
  fromChain: 42161,
  toChain: 999,
  fromToken: { symbol: 'USDC', address: '0x...', decimals: 6 },
  toToken: { symbol: 'USDC', address: '0x...', decimals: 6 },
  fromAmount: '100000000',
  toAmount: '99850000',        // Amount after fees
  estimatedTime: 120,          // Seconds
  gasCostUSD: '0.45',
  route: { ... }               // Bridge route details
}

Step 5: Execute the Bridge

Execute the bridge transaction using a viem wallet client. The SDK handles token approval, bridge execution, and auto-deposit.
import { createWalletClient, custom } from 'viem';
import { arbitrum } from 'viem/chains';

// Create a wallet client (browser environment with MetaMask)
const walletClient = createWalletClient({
  chain: arbitrum,
  transport: custom(window.ethereum)
});

// Get the connected account
const [account] = await walletClient.getAddresses();

// Execute the bridge
const result = await mina.execute({
  quote,
  walletClient,
  account,
  onStepChange: (step) => {
    console.log(`Step: ${step.type} - ${step.status}`);
  }
});

console.log('Bridge completed!');
console.log(`  Transaction hash: ${result.transactionHash}`);
console.log(`  Deposited to L1: ${result.depositedToL1}`);
Always ensure the user has sufficient native token balance for gas fees before executing. The SDK will throw an error if gas estimation fails.

Complete Example

Here is a complete, working example that bridges 100 USDC from Arbitrum to Hyperliquid:
import { Mina } from '@siphoyawe/mina-sdk';
import { createWalletClient, custom, parseUnits } from 'viem';
import { arbitrum } from 'viem/chains';

async function bridgeToHyperliquid() {
  // 1. Initialize the SDK
  const mina = new Mina({
    integrator: 'my-app',
    autoDeposit: true,
    defaultSlippage: 0.005
  });

  // 2. Create wallet client (browser with MetaMask)
  const walletClient = createWalletClient({
    chain: arbitrum,
    transport: custom(window.ethereum)
  });

  // 3. Get connected account
  const [account] = await walletClient.getAddresses();
  console.log(`Connected wallet: ${account}`);

  // 4. Get available tokens on Arbitrum
  const { tokens } = await mina.getTokens(42161);
  const usdc = tokens.find(t => t.symbol === 'USDC');

  if (!usdc) {
    throw new Error('USDC not found on Arbitrum');
  }

  // 5. Get a quote for 100 USDC
  const amount = parseUnits('100', 6).toString(); // 100 USDC

  const quote = await mina.getQuote({
    fromChain: 42161,
    toChain: 999,
    fromToken: usdc.address,
    toToken: '0x0000000000000000000000000000000000000000',
    amount,
    fromAddress: account
  });

  console.log(`Quote: Bridge ${quote.fromAmount} USDC`);
  console.log(`  Receive: ~${quote.toAmount} USDC`);
  console.log(`  Est. time: ${quote.estimatedTime}s`);

  // 6. Execute the bridge
  const result = await mina.execute({
    quote,
    walletClient,
    account,
    onStepChange: (step) => {
      console.log(`[${step.type}] ${step.status}: ${step.message || ''}`);
    }
  });

  console.log('Bridge complete!');
  console.log(`  TX Hash: ${result.transactionHash}`);
  console.log(`  Deposited to L1: ${result.depositedToL1}`);

  return result;
}

// Run the bridge
bridgeToHyperliquid()
  .then(result => console.log('Success!', result))
  .catch(error => console.error('Failed:', error));

What Happens During Execution

When you call mina.execute(), the SDK performs the following steps automatically:
1

Validate Quote

Verifies the quote is still valid and has not expired.
2

Check Allowance

Checks if the bridge contract has permission to spend your tokens.
3

Approve Tokens (if needed)

Prompts for token approval if the current allowance is insufficient.
4

Submit Bridge Transaction

Signs and submits the cross-chain bridge transaction.
5

Wait for Confirmation

Waits for the source chain transaction to be confirmed.
6

Monitor Bridge Progress

Tracks the cross-chain message until USDC arrives on HyperEVM.
7

Auto-Deposit (if enabled)

Detects USDC arrival, approves the deposit contract, and deposits to Hyperliquid L1.
8

Confirm L1 Balance

Verifies the deposit is reflected in your Hyperliquid trading account.
The onStepChange callback keeps you informed of progress throughout this process.

Next Steps

Now that you have completed your first bridge, explore these topics to learn more:

Configuration

Learn about all configuration options including custom RPCs and slippage settings.

React Hooks

Use the SDK with React hooks for a seamless UI integration.

Quote Options

Understand route preferences, slippage, and quote parameters.

Error Handling

Handle errors gracefully with typed error classes and recovery actions.