HyperFlow Dex Aggregator Integration

Architecture diagram

Get quote

GET https://ag-api.hyperflow.fun/v1/hyperevm/quote

Retrieves the optimal trading route and price quote between two tokens

Parameters

  • tokenIn : token input address

  • tokenOut: token output address

  • amountIn: amount of token input (in wei)

  • exchanges (optional): comma-separated list of decentralized exchange ids used in the route, if it will be blank so the system will route through all existing liquid sources availability.

  • gasPrice (optional): custom gas price (in wei)

Response

  • amountIn: amount input in wei

  • amountInUsd: amount input in USD

  • amountOut: amount output in wei

  • amountOutUsd: amount output in USD

  • splits

    • amountIn: amount token in (in wei)

    • amountOut: amount token out (in wei)

    • swaps: paths in detailed

Get swap data

GET https://ag-api.hyperflow.fun/v1/hyperevm/swap

Generates the transaction data needed to execute the swap through the router contract

Parameters

Includes all Quote API parameters, plus:

  • receiver: recipient address for output token

  • slippage: maximum acceptable slippage (0-1, e.g., 0.01 = 1%)

  • minAmountOut: custom minimum acceptable output amount

  • deadline(optional): transaction deadline in Unix seconds (default: now + 20 mins)

Response

Includes Quote API response, plus:

  • tx

    • data: encoded calldata for router

    • router: router contract address

Code example

// import {ethers} from 'ethers'; // ^6.13.4
import type {TransactionRequest} from 'ethers';

const routerApiUrl = 'router-API';
const rpcUrl = 'network-RPC'; // Replace with your Network RPC
const privateKey = 'your-private-key-here'; // Replace with your private key

const wallet = new ethers.Wallet(privateKey);

// Connect to a provider (e.g., Infura or any Ethereum node)
const provider = new ethers.JsonRpcProvider(rpcUrl);

// Utility
async function signAndSendTransaction(tx: TransactionRequest) {
  try {
    const signer = wallet.connect(provider);

    if (!tx.gasLimit) {
      // Estimate the transaction gas
      const estimatedGas = await signer.estimateGas(tx);
      tx.gasLimit = estimatedGas * BigInt(120) / BigInt(100);
    }

    // Sign the transaction
    const signedTx = await wallet.signTransaction(tx);
    console.log('Signed Transaction:', signedTx);

    // Send the signed transaction to the network
    const txResponse = await signer.sendTransaction(tx);
    console.log('Transaction Hash:', txResponse.hash);

    // Wait for the transaction to be mined (optional)
    const receipt = await txResponse.wait();
    console.log('Transaction Mined:', receipt);

    return receipt;
  } catch (error) {
    console.error('Error:', error);
    throw error;
  }
}

type Address = `0x${string}`

export const EtherAddress = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'

const erc20Abi = [
  {
    "constant": true,
    "inputs": [{"name": "_owner", "type": "address"}, {"name": "_spender", "type": "address"}],
    "name": "allowance",
    "outputs": [{"name": "remaining", "type": "uint256"}],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
  },
  {
    "constant": false,
    "inputs": [{"name": "_spender", "type": "address"}, {"name": "_value", "type": "uint256"}],
    "name": "approve",
    "outputs": [],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
  }
]

async function approve(token: Address, spender: Address, amount: string | bigint) {
  const contract = new ethers.Contract(token, erc20Abi, provider);

  const allowance = await contract.allowance(wallet.address, spender);

  if (allowance < BigInt(amount)) {
    const data = contract.interface.encodeFunctionData('approve', [spender, amount]);
    return signAndSendTransaction({to: token, data})
  }
  return Promise.resolve(true);
}

function serializeParameters(params: Record<string, any>) {
  const searchParams = new URLSearchParams(
    Object.fromEntries(Object.entries(params).filter(([_, v]) => !!v))
  );
  return searchParams.toString();
}

interface Swap {
  amountIn: string;
  amountOut: string;
  data: string;
  exchange: string;
  pool: Address;
  tokenIn: Address;
  tokenOut: Address;
  type: string;
}

interface Split {
  amountIn: string;
  amountOut: string;
  swaps: Swap[];
}

interface QuoteResponse {
  amountIn: string;
  amountInUsd: number;
  amountOut: string;
  amountOutUsd: number;
  minAmountOut: string;
  splits: Split[];
  tokenIn: Address;
  tokenOut: Address;
}

interface Transaction {
  data: string;
  router: Address;
}

interface SwapResponse {
  quote: QuoteResponse;
  tx: Transaction;
}

interface QuoteParameters {
  tokenIn: Address;
  tokenOut: Address;
  amountIn: string | bigint;
  exchanges?: string[];
}

// Retrieves the optimal trading route and price quote between two tokens
export async function quote(args: QuoteParameters): Promise<QuoteResponse> {
  const params = {
    ...args,
    amountIn: args.amountIn.toString(),
    exchanges: args.exchanges?.join(','),
  };
  const quoteResponse = await fetch(`${routerApiUrl}/quote?${serializeParameters(params)}`);
  return quoteResponse.json();
}

interface SwapParameters extends QuoteParameters {
  slippage?: number;
  receiver?: Address;
}

// Generates the transaction data needed to execute the swap through the router contract
export async function swap(args: SwapParameters) {
  const params = {
    ...args,
    amountIn: args.amountIn.toString(),
    exchanges: args.exchanges?.join(','),
    slippage: args?.slippage?.toString(),
    receiver: args.receiver || wallet.address,
  };
  // get encoded transaction data
  const encodingResponse = await fetch(`${routerApiUrl}/swap?${serializeParameters(params)}`);
  const encodingResult: SwapResponse = await encodingResponse.json();

  const tokenInIsNative = args.tokenIn.toLowerCase() === EtherAddress.toLowerCase();

  if (!tokenInIsNative) {
    // approve ERC20
    await approve(args.tokenIn, encodingResult.tx.router, args.amountIn);
  }

  return await signAndSendTransaction({
    to: encodingResult.tx.router,
    value: tokenInIsNative ? args.amountIn : undefined,
    data: encodingResult.tx.data,
  });
}

Authentication

HyperFlow secures your API requests through your account’s API keys. Once configured, ensure you include your key using the x-api-key header parameter in your requests. By default, the rate limit is 5 rps. Using your api key, the rate limit will be upgraged to 15 rps.

To obtain an API key, please reach out to the HyperFlow team via our Discord channel

Resources

Swagger:

https://ag-api.hyperflow.fun/v1/hyperevm/swagger/index.html

Last updated