A complete guide to wiring AKKA’s API into a wagmi + viem frontend. By the end, you’ll have a working swap flow: connect wallet, check allowance, approve, and execute.Documentation Index
Fetch the complete documentation index at: https://docs.akka.finance/llms.txt
Use this file to discover all available pages before exploring further.
Prerequisites
npm install wagmi viem @tanstack/react-query
1. Chain Configuration
Define HyperEVM as a custom chain for wagmi:config.ts
import { defineChain } from 'viem';
import { createConfig, http } from 'wagmi';
export const hyperEVM = defineChain({
id: 999,
name: 'HyperEVM',
nativeCurrency: { name: 'HYPE', symbol: 'HYPE', decimals: 18 },
rpcUrls: {
default: { http: ['https://rpc.hyperliquid.xyz/evm'] },
},
blockExplorers: {
default: { name: 'HyperEVM Scan', url: 'https://hyperevmscan.io' },
},
});
export const config = createConfig({
chains: [hyperEVM],
transports: {
[hyperEVM.id]: http(),
},
});
2. AKKA API Client
A thin wrapper around the AKKA API:akka.ts
const API_BASE = 'https://api.akka.finance';
const API_KEY = process.env.NEXT_PUBLIC_AKKA_API_KEY!;
const NATIVE_TOKEN = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee';
const CHAIN_ID = 999;
async function akkaFetch<T>(path: string, params: Record<string, string>): Promise<T> {
const url = `${API_BASE}${path}?${new URLSearchParams(params)}`;
const res = await fetch(url, { headers: { apikey: API_KEY } });
if (!res.ok) {
const error = await res.json();
throw new Error(error.message || 'AKKA API error');
}
return res.json();
}
export async function getQuote(src: string, dst: string, amount: string) {
return akkaFetch<{
dstAmount: string;
srcToken?: { symbol: string; decimals: number };
dstToken?: { symbol: string; decimals: number };
gas?: string;
}>(`/swap/v1/${CHAIN_ID}/quote`, {
src, dst, amount,
includeTokensInfo: 'true',
includeGas: 'true',
});
}
export async function getSwap(
src: string, dst: string, amount: string,
from: string, slippage: number,
) {
return akkaFetch<{
dstAmount: string;
tx: { to: string; data: string; value: string; gasPrice: string; gas: string };
}>(`/swap/v1/${CHAIN_ID}/swap`, {
src, dst, amount, from,
slippage: slippage.toString(),
});
}
export async function getAllowance(tokenAddress: string, walletAddress: string) {
return akkaFetch<{ allowance: string }>(
`/swap/v1/${CHAIN_ID}/approve/allowance`,
{ tokenAddress, walletAddress },
);
}
export async function getApproveTransaction(tokenAddress: string) {
return akkaFetch<{ data: string; to: string; value: string; gasPrice: string }>(
`/swap/v1/${CHAIN_ID}/approve/transaction`,
{ tokenAddress },
);
}
export function isNativeToken(address: string) {
return address.toLowerCase() === NATIVE_TOKEN;
}
3. Connect Wallet + Execute Swap
Wire the API client into wagmi hooks:SwapButton.tsx
import { useAccount, useSendTransaction, useWaitForTransactionReceipt } from 'wagmi';
import { useState } from 'react';
import { getSwap, getAllowance, getApproveTransaction, isNativeToken } from './akka';
interface SwapButtonProps {
src: string;
dst: string;
amount: string; // in wei
slippage: number;
}
export function SwapButton({ src, dst, amount, slippage }: SwapButtonProps) {
const { address } = useAccount();
const { sendTransactionAsync } = useSendTransaction();
const [status, setStatus] = useState<'idle' | 'approving' | 'swapping' | 'done' | 'error'>('idle');
const [txHash, setTxHash] = useState<string>();
const [error, setError] = useState<string>();
const handleSwap = async () => {
if (!address) return;
setError(undefined);
try {
// Step 1: Check & handle approval (skip for native tokens)
if (!isNativeToken(src)) {
setStatus('approving');
const { allowance } = await getAllowance(src, address);
if (BigInt(allowance) < BigInt(amount)) {
const approveTx = await getApproveTransaction(src);
const approveHash = await sendTransactionAsync({
to: approveTx.to as `0x${string}`,
data: approveTx.data as `0x${string}`,
value: BigInt(approveTx.value),
});
// Wait for approval to confirm before swapping
await waitForReceipt(approveHash);
}
}
// Step 2: Execute swap
setStatus('swapping');
const swap = await getSwap(src, dst, amount, address, slippage);
const { tx } = swap;
const hash = await sendTransactionAsync({
to: tx.to as `0x${string}`,
data: tx.data as `0x${string}`,
value: BigInt(tx.value),
gasPrice: BigInt(tx.gasPrice),
gas: BigInt(tx.gas),
});
setTxHash(hash);
setStatus('done');
} catch (err) {
setError(err instanceof Error ? err.message : 'Swap failed');
setStatus('error');
}
};
return (
<div>
<button onClick={handleSwap} disabled={!address || status === 'approving' || status === 'swapping'}>
{status === 'approving' && 'Approving...'}
{status === 'swapping' && 'Swapping...'}
{status === 'idle' && 'Swap'}
{status === 'done' && 'Done!'}
{status === 'error' && 'Retry'}
</button>
{error && <p style={{ color: 'red' }}>{error}</p>}
{txHash && (
<a href={`https://hyperevmscan.io/tx/${txHash}`} target="_blank" rel="noreferrer">
View transaction
</a>
)}
</div>
);
}
async function waitForReceipt(hash: string): Promise<void> {
// Simple polling — in production, use wagmi's useWaitForTransactionReceipt
const { createPublicClient, http } = await import('viem');
const client = createPublicClient({ transport: http('https://rpc.hyperliquid.xyz/evm') });
await client.waitForTransactionReceipt({ hash: hash as `0x${string}` });
}
4. Full Page Example
Putting it all together:SwapPage.tsx
import { useAccount, useConnect } from 'wagmi';
import { injected } from 'wagmi/connectors';
import { useState } from 'react';
import { parseUnits } from 'viem';
import { SwapButton } from './SwapButton';
import { useAkkaQuote } from './hooks'; // see React Hooks guide
const HYPE = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee';
const UBTC = '0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb';
export function SwapPage() {
const { address, isConnected } = useAccount();
const { connect } = useConnect();
const [inputAmount, setInputAmount] = useState('');
const amountWei = inputAmount ? parseUnits(inputAmount, 18).toString() : '0';
const { quote, loading } = useAkkaQuote(HYPE, UBTC, amountWei);
if (!isConnected) {
return <button onClick={() => connect({ connector: injected() })}>Connect Wallet</button>;
}
return (
<div>
<input
type="number"
placeholder="Amount in HYPE"
value={inputAmount}
onChange={(e) => setInputAmount(e.target.value)}
/>
{loading && <p>Fetching quote...</p>}
{quote && <p>You'll receive: {(Number(quote.dstAmount) / 1e18).toFixed(6)} UBTC</p>}
<SwapButton src={HYPE} dst={UBTC} amount={amountWei} slippage={1} />
</div>
);
}
See the React Hooks guide for the
useAkkaQuote and useAkkaSwap hooks used above.