Two ways to build on AkaFun: attach a referrer to any swap, or launch tokens straight from your own app. Both are permissionless.
This guide covers two ways to build on top of AkaFun. Everything below is described against Arc, the only network currently deployed.
Attach a referrer address to a swap and earn an ongoing commission. No signup, no API key.
Deploy AkaFun tokens directly, without going through akadotfun.com's own UI.
Arc, chain ID 5042. Addresses change with a redeploy.
Any app that routes a user's swap through an AkaFun token's pool can attach a referrer address to that swap and earn an ongoing commission. Permissionless, no signup required.
Referral logic only runs on the specific pool created at that token's launch, not any other pool for the same pair. Native currency always sorts as currency0, so the token being traded is always currency1.
currency0 = 0x0000000000000000000000000000000000000000 // native currency, always currency1 = <the AkaFun token address> fee = 0 tickSpacing = 1 hooks = 0x61d3117023D827f4851e88a7CAD5C7bD49e4C4Cc // AkaFunHook, always
You can route the swap through any Uniswap v4-compatible router: Uniswap's own Universal Router, your own router, or anything else that can execute a v4 swap against an arbitrary pool key and pass hookData through. Nothing about referral or fee logic depends on which router initiates the swap. It fires based on which pool is being traded against, checked by the pool manager itself, not by any allow-list of routers.
A swap's hookData bytes carry the referral info. No struct, just a length-based convention. hookData is fully optional: missing or malformed data never breaks the swap, it just means no referrer gets credited.
import { encodeAbiParameters, parseAbiParameters } from "viem";
const referrerHookData = encodeAbiParameters(
parseAbiParameters("address"),
[referrerAddress]
); // pass this as the swap action's hookDataEvery swap pays a flat 2.00% fee, denominated in native currency. If a level is missing, its share folds up to the next present level rather than being lost: a trader with only a Level 1 referrer sends that referrer the full 15% share, not just 50% of it. With no referrer at all, that 15% stays with the platform.
By default the trader is credited as tx.origin. If your app routes swaps through a relayer, smart-contract wallet, or bundler, where tx.origin isn't the real end user, use the 64-byte hookData form to declare the actual trader. That declaration is only honored if it matches tx.origin, or if your relayer address has been allow-listed by AkaFun; otherwise it's silently ignored and tx.origin is used instead. Reach out to get your relayer address allow-listed if you need this.
This allow-list only affects whose trader claim is trusted. Swapping and earning referral commission itself requires no permission at all.
A user's referrer is set once, permanently, first-write-wins. Three ways to set it.
The first swap carrying a referrer registers it.
If you're also doing a launch integration, the launch's referrer field registers the launching user.
Call updateRefFromUser(referrer) as the invited user, independent of any trade. Reverts if the caller already has a referrer or if it would create a self-referral cycle.
function getReferralTree(address trader) external view returns (address[3] memory); // returns [level1, level2, level3]
Deploy tokens from your own app. Total supply is always exactly 1,000,000,000 tokens (18 decimals), seeded 100% into the launch pool. Not configurable through this interface.
function deployToken(DeploymentConfig calldata deploymentConfig)
external payable returns (address tokenAddress);deployToken uses the caller as the token's creator — this is the only launch entry point. There is no way to launch a token attributed to a different address than the one submitting the transaction.
struct TokenConfig {
string name;
string symbol;
bytes32 salt; // must be strong randomness -- see address prediction below
string metadataUrl; // off-chain JSON (image/description/socials), never read on-chain
}
struct PoolConfig {
int24 tickIfToken0IsNewToken; // tickSpacing is 1, so any int24 is valid
uint128 liquidity;
}
struct InitialBuyConfig {
uint256 buyPairedAmount; // 0 = no initial buy
uint256 minTokenAmount; // slippage floor for the initial buy
}
struct DeploymentConfig {
InitialBuyConfig initialBuyConfig;
TokenConfig tokenConfig;
PoolConfig poolConfig;
address referrer;
bool enableDrop;
uint256 dropMinimumThreshold; // 0 auto-defaults to 100 native units
uint256 dropTicketValue; // 0 auto-defaults to 100 native units
PoolKey[] stockPools; // RWA backing -- see below
uint256 reserveShare; // 0-90_000 (against 100_000 = 100%); 0 = full supply into the pool
address reserveRecipient; // address(0) (default) falls back to the creator
}function deployFee() external view returns (uint256);
msg.value must equal exactly deployFee() + initialBuyConfig.buyPairedAmount, not “at least.” Query deployFee() right before you build the transaction; it can change.
bytecode = abi.encodePacked(
tokenCreationCode,
abi.encode(name, symbol, TOKEN_SUPPLY, creator, AkaFunLauncherAddress)
)
codeHash = keccak256(bytecode)
salt = keccak256(abi.encode(creator, tokenConfig.salt))
address = Create2.computeAddress(salt, codeHash, create2DeployerAddress)Two details that are easy to get wrong.
stockPools is a list of up to 4 Uniswap v4 pool keys the launch can back itself with. Every entry is checked against an on-chain approval registry AkaFunHook admins maintain, so you cannot back a launch with a pool of your own choosing.
Read the approved set before you build the transaction rather than hardcoding pool keys: approval is admin state and can change.
Set initialBuyConfig.buyPairedAmount > 0 to have the launch immediately buy the new token with native currency, sent to the creator. This initial buy carries no referral data: only the pool's own creation step, which carries deploymentConfig.referrer, registers a referral relationship.
event TokenCreated(
uint256 lpTokenId,
address tokenAddress,
address indexed creatorAddress,
string symbol,
int24 startingTickIfToken0IsNewToken,
uint256 amountTokensBought,
address stakingAddress,
address dropAddress,
address treasuryAddress,
string metadataUrl,
uint256 reserveShare,
uint256 reserveAmount,
address reserveRecipient
);function getTokensDeployedByUser(address user) external view returns (DeploymentInfo[] memory);
Addresses, fees, and thresholds can change with a redeploy. Read them from this page rather than pinning them.
Both integrations are fully permissionless. No API key or agreement needed. The only exception is the relayer allow-list for trader attribution, which only matters if you relay transactions.
Two ways to build on AkaFun: attach a referrer to any swap, or launch tokens straight from your own app. Both are permissionless.
This guide covers two ways to build on top of AkaFun. Everything below is described against Arc, the only network currently deployed.
Attach a referrer address to a swap and earn an ongoing commission. No signup, no API key.
Deploy AkaFun tokens directly, without going through akadotfun.com's own UI.
Arc, chain ID 5042. Addresses change with a redeploy.
Any app that routes a user's swap through an AkaFun token's pool can attach a referrer address to that swap and earn an ongoing commission. Permissionless, no signup required.
Referral logic only runs on the specific pool created at that token's launch, not any other pool for the same pair. Native currency always sorts as currency0, so the token being traded is always currency1.
currency0 = 0x0000000000000000000000000000000000000000 // native currency, always currency1 = <the AkaFun token address> fee = 0 tickSpacing = 1 hooks = 0x61d3117023D827f4851e88a7CAD5C7bD49e4C4Cc // AkaFunHook, always
You can route the swap through any Uniswap v4-compatible router: Uniswap's own Universal Router, your own router, or anything else that can execute a v4 swap against an arbitrary pool key and pass hookData through. Nothing about referral or fee logic depends on which router initiates the swap. It fires based on which pool is being traded against, checked by the pool manager itself, not by any allow-list of routers.
A swap's hookData bytes carry the referral info. No struct, just a length-based convention. hookData is fully optional: missing or malformed data never breaks the swap, it just means no referrer gets credited.
import { encodeAbiParameters, parseAbiParameters } from "viem";
const referrerHookData = encodeAbiParameters(
parseAbiParameters("address"),
[referrerAddress]
); // pass this as the swap action's hookDataEvery swap pays a flat 2.00% fee, denominated in native currency. If a level is missing, its share folds up to the next present level rather than being lost: a trader with only a Level 1 referrer sends that referrer the full 15% share, not just 50% of it. With no referrer at all, that 15% stays with the platform.
By default the trader is credited as tx.origin. If your app routes swaps through a relayer, smart-contract wallet, or bundler, where tx.origin isn't the real end user, use the 64-byte hookData form to declare the actual trader. That declaration is only honored if it matches tx.origin, or if your relayer address has been allow-listed by AkaFun; otherwise it's silently ignored and tx.origin is used instead. Reach out to get your relayer address allow-listed if you need this.
This allow-list only affects whose trader claim is trusted. Swapping and earning referral commission itself requires no permission at all.
A user's referrer is set once, permanently, first-write-wins. Three ways to set it.
The first swap carrying a referrer registers it.
If you're also doing a launch integration, the launch's referrer field registers the launching user.
Call updateRefFromUser(referrer) as the invited user, independent of any trade. Reverts if the caller already has a referrer or if it would create a self-referral cycle.
function getReferralTree(address trader) external view returns (address[3] memory); // returns [level1, level2, level3]
Deploy tokens from your own app. Total supply is always exactly 1,000,000,000 tokens (18 decimals), seeded 100% into the launch pool. Not configurable through this interface.
function deployToken(DeploymentConfig calldata deploymentConfig)
external payable returns (address tokenAddress);deployToken uses the caller as the token's creator — this is the only launch entry point. There is no way to launch a token attributed to a different address than the one submitting the transaction.
struct TokenConfig {
string name;
string symbol;
bytes32 salt; // must be strong randomness -- see address prediction below
string metadataUrl; // off-chain JSON (image/description/socials), never read on-chain
}
struct PoolConfig {
int24 tickIfToken0IsNewToken; // tickSpacing is 1, so any int24 is valid
uint128 liquidity;
}
struct InitialBuyConfig {
uint256 buyPairedAmount; // 0 = no initial buy
uint256 minTokenAmount; // slippage floor for the initial buy
}
struct DeploymentConfig {
InitialBuyConfig initialBuyConfig;
TokenConfig tokenConfig;
PoolConfig poolConfig;
address referrer;
bool enableDrop;
uint256 dropMinimumThreshold; // 0 auto-defaults to 100 native units
uint256 dropTicketValue; // 0 auto-defaults to 100 native units
PoolKey[] stockPools; // RWA backing -- see below
uint256 reserveShare; // 0-90_000 (against 100_000 = 100%); 0 = full supply into the pool
address reserveRecipient; // address(0) (default) falls back to the creator
}function deployFee() external view returns (uint256);
msg.value must equal exactly deployFee() + initialBuyConfig.buyPairedAmount, not “at least.” Query deployFee() right before you build the transaction; it can change.
bytecode = abi.encodePacked(
tokenCreationCode,
abi.encode(name, symbol, TOKEN_SUPPLY, creator, AkaFunLauncherAddress)
)
codeHash = keccak256(bytecode)
salt = keccak256(abi.encode(creator, tokenConfig.salt))
address = Create2.computeAddress(salt, codeHash, create2DeployerAddress)Two details that are easy to get wrong.
stockPools is a list of up to 4 Uniswap v4 pool keys the launch can back itself with. Every entry is checked against an on-chain approval registry AkaFunHook admins maintain, so you cannot back a launch with a pool of your own choosing.
Read the approved set before you build the transaction rather than hardcoding pool keys: approval is admin state and can change.
Set initialBuyConfig.buyPairedAmount > 0 to have the launch immediately buy the new token with native currency, sent to the creator. This initial buy carries no referral data: only the pool's own creation step, which carries deploymentConfig.referrer, registers a referral relationship.
event TokenCreated(
uint256 lpTokenId,
address tokenAddress,
address indexed creatorAddress,
string symbol,
int24 startingTickIfToken0IsNewToken,
uint256 amountTokensBought,
address stakingAddress,
address dropAddress,
address treasuryAddress,
string metadataUrl,
uint256 reserveShare,
uint256 reserveAmount,
address reserveRecipient
);function getTokensDeployedByUser(address user) external view returns (DeploymentInfo[] memory);
Addresses, fees, and thresholds can change with a redeploy. Read them from this page rather than pinning them.
Both integrations are fully permissionless. No API key or agreement needed. The only exception is the relayer allow-list for trader attribution, which only matters if you relay transactions.