Docs / Integration
IntegrationMainnet

Two ways to build on AkaFun: attach a referrer to any swap, or launch tokens straight from your own app. Both are permissionless.

00 / Overview

Third-party integration

This guide covers two ways to build on top of AkaFun. Everything below is described against Arc, the only network currently deployed.

1Referral integration
Any swap app can earn commission

Attach a referrer address to a swap and earn an ongoing commission. No signup, no API key.

2Launch integration
Create tokens from your own app

Deploy AkaFun tokens directly, without going through akadotfun.com's own UI.

Network
Arc
Chain ID
5042
Swap fee
2.00%
To referrers
15% of fee
01 / Contracts

Contract addresses

Arc, chain ID 5042. Addresses change with a redeploy.

Deployed contracts
AkaFunLauncher0x7898Dd4bD730677ea0cBe6eEcEB2545D6a262b7BLaunching tokens
AkaFunHook0x61d3117023D827f4851e88a7CAD5C7bD49e4C4CcThe hook attached to every AkaFun token's pool
AkaFunReferral0x8189D359777fB90fE3DFfAf3cBBB78B2A6c50b43Reading and registering referral relationships
Permit20x000000000022D473030F116dDEE9F6B43aC78BA3Token approvals, needed when selling a token into a swap
Create2Deployer0x4a9872793BFaA23bB1C7675A25f9d71a582E6a66Predicting a token's address before launch
02 / Referral

Attach a referrer to any swap

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.

Which pool to swap against

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.

Attaching a referrer · hookData
32 bytesReferrer only — abi.encode(referrerAddress)
64 bytesTrader + referrer — abi.encode(traderAddress, referrerAddress)
Anything else, including emptyNo referral

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 hookData
Fee split · 15% of the fee, 0.30% of swap volume
Level 1 · direct
50%
Level 2
30%
Level 3
20%

Every 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.

If you relay or bundle transactions

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.

Registering a referrer

A user's referrer is set once, permanently, first-write-wins. Three ways to set it.

01 / Via swap hookData

The first swap carrying a referrer registers it.

02 / At launch time

If you're also doing a launch integration, the launch's referrer field registers the launching user.

03 / Directly

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]
03 / Launch

Create AkaFun tokens directly

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.

Entry points
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.

DeploymentConfig
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
}
deployFee() and msg.value
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.

Predicting the token address before deploying
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.

Launcher argumentThe constructor's launcher argument must be the AkaFunLauncher address above, not any other address. Get this wrong and your predicted address won't match what actually deploys.
tokenConfig.saltMust be strong, unpredictable randomness you generate yourself, never sequential or fixed. The deployer factory is shared and permissionless, so a predictable salt makes an already-broadcast launch transaction front-runnable.
RWA backing (stockPools) — admin-approved pools only

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.

EmptyNo RWA backing is configured, and no Treasury is deployed. That share of the swap fee (30%) goes to the creator instead, so their total share becomes 60% (30% base + 30% folded in).
An unapproved poolThe launch reverts with UnapprovedStockPool(index). Nothing is deployed and no fee is taken, so this fails loudly rather than producing a token whose buyback does nothing.
An approved poolAlso has to be structurally valid: currency0 must be the native currency and the pool must be hookless, or the Treasury constructor reverts with InvalidPool. Accepted pools are fixed at construction, with no way to change them later.

Read the approved set before you build the transaction rather than hardcoding pool keys: approval is admin state and can change.

Initial buy (optional)

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.

TokenCreated event
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
);
amountTokensBoughtThe slippage floor you supplied (minTokenAmount), not the actual swap output. Don't treat it as an exact figure.
stakingAddressAlways equals tokenAddress. Every token is its own staking contract.
dropAddress / treasuryAddressThe zero address if that launch opted out of either.
Reading a user's launched tokens
function getTokensDeployedByUser(address user) external view returns (DeploymentInfo[] memory);
04 / Notes

A few things to keep in mind

Subject to change

Addresses, fees, and thresholds can change with a redeploy. Read them from this page rather than pinning them.

Permissionless

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.

Docs / Integration
IntegrationMainnet

Two ways to build on AkaFun: attach a referrer to any swap, or launch tokens straight from your own app. Both are permissionless.

00 / Overview

Third-party integration

This guide covers two ways to build on top of AkaFun. Everything below is described against Arc, the only network currently deployed.

1Referral integration
Any swap app can earn commission

Attach a referrer address to a swap and earn an ongoing commission. No signup, no API key.

2Launch integration
Create tokens from your own app

Deploy AkaFun tokens directly, without going through akadotfun.com's own UI.

Network
Arc
Chain ID
5042
Swap fee
2.00%
To referrers
15% of fee
01 / Contracts

Contract addresses

Arc, chain ID 5042. Addresses change with a redeploy.

Deployed contracts
AkaFunLauncher0x7898Dd4bD730677ea0cBe6eEcEB2545D6a262b7BLaunching tokens
AkaFunHook0x61d3117023D827f4851e88a7CAD5C7bD49e4C4CcThe hook attached to every AkaFun token's pool
AkaFunReferral0x8189D359777fB90fE3DFfAf3cBBB78B2A6c50b43Reading and registering referral relationships
Permit20x000000000022D473030F116dDEE9F6B43aC78BA3Token approvals, needed when selling a token into a swap
Create2Deployer0x4a9872793BFaA23bB1C7675A25f9d71a582E6a66Predicting a token's address before launch
02 / Referral

Attach a referrer to any swap

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.

Which pool to swap against

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.

Attaching a referrer · hookData
32 bytesReferrer only — abi.encode(referrerAddress)
64 bytesTrader + referrer — abi.encode(traderAddress, referrerAddress)
Anything else, including emptyNo referral

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 hookData
Fee split · 15% of the fee, 0.30% of swap volume
Level 1 · direct
50%
Level 2
30%
Level 3
20%

Every 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.

If you relay or bundle transactions

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.

Registering a referrer

A user's referrer is set once, permanently, first-write-wins. Three ways to set it.

01 / Via swap hookData

The first swap carrying a referrer registers it.

02 / At launch time

If you're also doing a launch integration, the launch's referrer field registers the launching user.

03 / Directly

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]
03 / Launch

Create AkaFun tokens directly

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.

Entry points
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.

DeploymentConfig
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
}
deployFee() and msg.value
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.

Predicting the token address before deploying
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.

Launcher argumentThe constructor's launcher argument must be the AkaFunLauncher address above, not any other address. Get this wrong and your predicted address won't match what actually deploys.
tokenConfig.saltMust be strong, unpredictable randomness you generate yourself, never sequential or fixed. The deployer factory is shared and permissionless, so a predictable salt makes an already-broadcast launch transaction front-runnable.
RWA backing (stockPools) — admin-approved pools only

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.

EmptyNo RWA backing is configured, and no Treasury is deployed. That share of the swap fee (30%) goes to the creator instead, so their total share becomes 60% (30% base + 30% folded in).
An unapproved poolThe launch reverts with UnapprovedStockPool(index). Nothing is deployed and no fee is taken, so this fails loudly rather than producing a token whose buyback does nothing.
An approved poolAlso has to be structurally valid: currency0 must be the native currency and the pool must be hookless, or the Treasury constructor reverts with InvalidPool. Accepted pools are fixed at construction, with no way to change them later.

Read the approved set before you build the transaction rather than hardcoding pool keys: approval is admin state and can change.

Initial buy (optional)

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.

TokenCreated event
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
);
amountTokensBoughtThe slippage floor you supplied (minTokenAmount), not the actual swap output. Don't treat it as an exact figure.
stakingAddressAlways equals tokenAddress. Every token is its own staking contract.
dropAddress / treasuryAddressThe zero address if that launch opted out of either.
Reading a user's launched tokens
function getTokensDeployedByUser(address user) external view returns (DeploymentInfo[] memory);
04 / Notes

A few things to keep in mind

Subject to change

Addresses, fees, and thresholds can change with a redeploy. Read them from this page rather than pinning them.

Permissionless

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.

) {} // keep closing markers } if(child.nodeType===1) walkComments(child); child=next; } } // Run on body as soon as it exists (this script is in head, so body may not exist yet) // Use MutationObserver to catch body if(document.body){ walkComments(document.body); } else { var obs=new MutationObserver(function(muts,o){ if(document.body){ walkComments(document.body); // Also unhide S:0 again after body is ready var s=document.getElementById('S:0'); if(s){s.removeAttribute('hidden');s.style.cssText='display:block!important';} o.disconnect(); } }); obs.observe(document.documentElement,{childList:true,subtree:true}); } })(); Aka Fun Launchpad on Arc - RWA Token Launcher & DEX
Docs / Integration
IntegrationMainnet

Two ways to build on AkaFun: attach a referrer to any swap, or launch tokens straight from your own app. Both are permissionless.

00 / Overview

Third-party integration

This guide covers two ways to build on top of AkaFun. Everything below is described against Arc, the only network currently deployed.

1Referral integration
Any swap app can earn commission

Attach a referrer address to a swap and earn an ongoing commission. No signup, no API key.

2Launch integration
Create tokens from your own app

Deploy AkaFun tokens directly, without going through akadotfun.com's own UI.

Network
Arc
Chain ID
5042
Swap fee
2.00%
To referrers
15% of fee
01 / Contracts

Contract addresses

Arc, chain ID 5042. Addresses change with a redeploy.

Deployed contracts
AkaFunLauncher0x7898Dd4bD730677ea0cBe6eEcEB2545D6a262b7BLaunching tokens
AkaFunHook0x61d3117023D827f4851e88a7CAD5C7bD49e4C4CcThe hook attached to every AkaFun token's pool
AkaFunReferral0x8189D359777fB90fE3DFfAf3cBBB78B2A6c50b43Reading and registering referral relationships
Permit20x000000000022D473030F116dDEE9F6B43aC78BA3Token approvals, needed when selling a token into a swap
Create2Deployer0x4a9872793BFaA23bB1C7675A25f9d71a582E6a66Predicting a token's address before launch
02 / Referral

Attach a referrer to any swap

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.

Which pool to swap against

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.

Attaching a referrer · hookData
32 bytesReferrer only — abi.encode(referrerAddress)
64 bytesTrader + referrer — abi.encode(traderAddress, referrerAddress)
Anything else, including emptyNo referral

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 hookData
Fee split · 15% of the fee, 0.30% of swap volume
Level 1 · direct
50%
Level 2
30%
Level 3
20%

Every 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.

If you relay or bundle transactions

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.

Registering a referrer

A user's referrer is set once, permanently, first-write-wins. Three ways to set it.

01 / Via swap hookData

The first swap carrying a referrer registers it.

02 / At launch time

If you're also doing a launch integration, the launch's referrer field registers the launching user.

03 / Directly

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]
03 / Launch

Create AkaFun tokens directly

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.

Entry points
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.

DeploymentConfig
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
}
deployFee() and msg.value
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.

Predicting the token address before deploying
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.

Launcher argumentThe constructor's launcher argument must be the AkaFunLauncher address above, not any other address. Get this wrong and your predicted address won't match what actually deploys.
tokenConfig.saltMust be strong, unpredictable randomness you generate yourself, never sequential or fixed. The deployer factory is shared and permissionless, so a predictable salt makes an already-broadcast launch transaction front-runnable.
RWA backing (stockPools) — admin-approved pools only

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.

EmptyNo RWA backing is configured, and no Treasury is deployed. That share of the swap fee (30%) goes to the creator instead, so their total share becomes 60% (30% base + 30% folded in).
An unapproved poolThe launch reverts with UnapprovedStockPool(index). Nothing is deployed and no fee is taken, so this fails loudly rather than producing a token whose buyback does nothing.
An approved poolAlso has to be structurally valid: currency0 must be the native currency and the pool must be hookless, or the Treasury constructor reverts with InvalidPool. Accepted pools are fixed at construction, with no way to change them later.

Read the approved set before you build the transaction rather than hardcoding pool keys: approval is admin state and can change.

Initial buy (optional)

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.

TokenCreated event
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
);
amountTokensBoughtThe slippage floor you supplied (minTokenAmount), not the actual swap output. Don't treat it as an exact figure.
stakingAddressAlways equals tokenAddress. Every token is its own staking contract.
dropAddress / treasuryAddressThe zero address if that launch opted out of either.
Reading a user's launched tokens
function getTokensDeployedByUser(address user) external view returns (DeploymentInfo[] memory);
04 / Notes

A few things to keep in mind

Subject to change

Addresses, fees, and thresholds can change with a redeploy. Read them from this page rather than pinning them.

Permissionless

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.

; if(child.nodeType===1)walkComments(child); child=next; } } walkComments(document.body); // Remove templates that are still blocking (B:0, B:1) document.querySelectorAll('template[id^="B:"]').forEach(function(t){ var sid='S:'+t.id.slice(2); var sw=document.getElementById(sid); if(sw){ sw.removeAttribute('hidden'); // Move children before template var par=t.parentNode; while(sw.firstChild)par.insertBefore(sw.firstChild,t); sw.remove(); } t.remove(); }); // Remove any visible loading spinners (aria-live polite with spin animation) document.querySelectorAll('[role="status"][aria-live="polite"]').forEach(function(el){ if(el.querySelector('svg.animate-spin,svg[class*="animate-spin"]')){ el.remove(); } }); // Override React's $RV function to prevent it from hiding resolved suspense if(typeof window.$RV==='function'){ window.$RV_original=window.$RV; window.$RV=function(a){ // Still run original but then re-show S:0 try{window.$RV_original(a);}catch(e){} var s=document.getElementById('S:0'); if(s){s.removeAttribute('hidden');s.style.cssText='display:block!important';} }; } } // Run immediately fix(); // Run again after DOMContentLoaded document.addEventListener('DOMContentLoaded',fix); // Run again after React has a chance to hydrate (500ms delay) setTimeout(fix,100); setTimeout(fix,500); setTimeout(fix,1000); })(); ; if(child.data==='/Aka Fun Launchpad on Arc - RWA Token Launcher & DEX
Docs / Integration
IntegrationMainnet

Two ways to build on AkaFun: attach a referrer to any swap, or launch tokens straight from your own app. Both are permissionless.

00 / Overview

Third-party integration

This guide covers two ways to build on top of AkaFun. Everything below is described against Arc, the only network currently deployed.

1Referral integration
Any swap app can earn commission

Attach a referrer address to a swap and earn an ongoing commission. No signup, no API key.

2Launch integration
Create tokens from your own app

Deploy AkaFun tokens directly, without going through akadotfun.com's own UI.

Network
Arc
Chain ID
5042
Swap fee
2.00%
To referrers
15% of fee
01 / Contracts

Contract addresses

Arc, chain ID 5042. Addresses change with a redeploy.

Deployed contracts
AkaFunLauncher0x7898Dd4bD730677ea0cBe6eEcEB2545D6a262b7BLaunching tokens
AkaFunHook0x61d3117023D827f4851e88a7CAD5C7bD49e4C4CcThe hook attached to every AkaFun token's pool
AkaFunReferral0x8189D359777fB90fE3DFfAf3cBBB78B2A6c50b43Reading and registering referral relationships
Permit20x000000000022D473030F116dDEE9F6B43aC78BA3Token approvals, needed when selling a token into a swap
Create2Deployer0x4a9872793BFaA23bB1C7675A25f9d71a582E6a66Predicting a token's address before launch
02 / Referral

Attach a referrer to any swap

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.

Which pool to swap against

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.

Attaching a referrer · hookData
32 bytesReferrer only — abi.encode(referrerAddress)
64 bytesTrader + referrer — abi.encode(traderAddress, referrerAddress)
Anything else, including emptyNo referral

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 hookData
Fee split · 15% of the fee, 0.30% of swap volume
Level 1 · direct
50%
Level 2
30%
Level 3
20%

Every 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.

If you relay or bundle transactions

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.

Registering a referrer

A user's referrer is set once, permanently, first-write-wins. Three ways to set it.

01 / Via swap hookData

The first swap carrying a referrer registers it.

02 / At launch time

If you're also doing a launch integration, the launch's referrer field registers the launching user.

03 / Directly

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]
03 / Launch

Create AkaFun tokens directly

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.

Entry points
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.

DeploymentConfig
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
}
deployFee() and msg.value
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.

Predicting the token address before deploying
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.

Launcher argumentThe constructor's launcher argument must be the AkaFunLauncher address above, not any other address. Get this wrong and your predicted address won't match what actually deploys.
tokenConfig.saltMust be strong, unpredictable randomness you generate yourself, never sequential or fixed. The deployer factory is shared and permissionless, so a predictable salt makes an already-broadcast launch transaction front-runnable.
RWA backing (stockPools) — admin-approved pools only

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.

EmptyNo RWA backing is configured, and no Treasury is deployed. That share of the swap fee (30%) goes to the creator instead, so their total share becomes 60% (30% base + 30% folded in).
An unapproved poolThe launch reverts with UnapprovedStockPool(index). Nothing is deployed and no fee is taken, so this fails loudly rather than producing a token whose buyback does nothing.
An approved poolAlso has to be structurally valid: currency0 must be the native currency and the pool must be hookless, or the Treasury constructor reverts with InvalidPool. Accepted pools are fixed at construction, with no way to change them later.

Read the approved set before you build the transaction rather than hardcoding pool keys: approval is admin state and can change.

Initial buy (optional)

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.

TokenCreated event
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
);
amountTokensBoughtThe slippage floor you supplied (minTokenAmount), not the actual swap output. Don't treat it as an exact figure.
stakingAddressAlways equals tokenAddress. Every token is its own staking contract.
dropAddress / treasuryAddressThe zero address if that launch opted out of either.
Reading a user's launched tokens
function getTokensDeployedByUser(address user) external view returns (DeploymentInfo[] memory);
04 / Notes

A few things to keep in mind

Subject to change

Addresses, fees, and thresholds can change with a redeploy. Read them from this page rather than pinning them.

Permissionless

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.

) {} // keep closing markers } if(child.nodeType===1) walkComments(child); child=next; } } // Run on body as soon as it exists (this script is in head, so body may not exist yet) // Use MutationObserver to catch body if(document.body){ walkComments(document.body); } else { var obs=new MutationObserver(function(muts,o){ if(document.body){ walkComments(document.body); // Also unhide S:0 again after body is ready var s=document.getElementById('S:0'); if(s){s.removeAttribute('hidden');s.style.cssText='display:block!important';} o.disconnect(); } }); obs.observe(document.documentElement,{childList:true,subtree:true}); } })(); Aka Fun Launchpad on Arc - RWA Token Launcher & DEX
Docs / Integration
IntegrationMainnet

Two ways to build on AkaFun: attach a referrer to any swap, or launch tokens straight from your own app. Both are permissionless.

00 / Overview

Third-party integration

This guide covers two ways to build on top of AkaFun. Everything below is described against Arc, the only network currently deployed.

1Referral integration
Any swap app can earn commission

Attach a referrer address to a swap and earn an ongoing commission. No signup, no API key.

2Launch integration
Create tokens from your own app

Deploy AkaFun tokens directly, without going through akadotfun.com's own UI.

Network
Arc
Chain ID
5042
Swap fee
2.00%
To referrers
15% of fee
01 / Contracts

Contract addresses

Arc, chain ID 5042. Addresses change with a redeploy.

Deployed contracts
AkaFunLauncher0x7898Dd4bD730677ea0cBe6eEcEB2545D6a262b7BLaunching tokens
AkaFunHook0x61d3117023D827f4851e88a7CAD5C7bD49e4C4CcThe hook attached to every AkaFun token's pool
AkaFunReferral0x8189D359777fB90fE3DFfAf3cBBB78B2A6c50b43Reading and registering referral relationships
Permit20x000000000022D473030F116dDEE9F6B43aC78BA3Token approvals, needed when selling a token into a swap
Create2Deployer0x4a9872793BFaA23bB1C7675A25f9d71a582E6a66Predicting a token's address before launch
02 / Referral

Attach a referrer to any swap

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.

Which pool to swap against

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.

Attaching a referrer · hookData
32 bytesReferrer only — abi.encode(referrerAddress)
64 bytesTrader + referrer — abi.encode(traderAddress, referrerAddress)
Anything else, including emptyNo referral

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 hookData
Fee split · 15% of the fee, 0.30% of swap volume
Level 1 · direct
50%
Level 2
30%
Level 3
20%

Every 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.

If you relay or bundle transactions

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.

Registering a referrer

A user's referrer is set once, permanently, first-write-wins. Three ways to set it.

01 / Via swap hookData

The first swap carrying a referrer registers it.

02 / At launch time

If you're also doing a launch integration, the launch's referrer field registers the launching user.

03 / Directly

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]
03 / Launch

Create AkaFun tokens directly

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.

Entry points
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.

DeploymentConfig
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
}
deployFee() and msg.value
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.

Predicting the token address before deploying
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.

Launcher argumentThe constructor's launcher argument must be the AkaFunLauncher address above, not any other address. Get this wrong and your predicted address won't match what actually deploys.
tokenConfig.saltMust be strong, unpredictable randomness you generate yourself, never sequential or fixed. The deployer factory is shared and permissionless, so a predictable salt makes an already-broadcast launch transaction front-runnable.
RWA backing (stockPools) — admin-approved pools only

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.

EmptyNo RWA backing is configured, and no Treasury is deployed. That share of the swap fee (30%) goes to the creator instead, so their total share becomes 60% (30% base + 30% folded in).
An unapproved poolThe launch reverts with UnapprovedStockPool(index). Nothing is deployed and no fee is taken, so this fails loudly rather than producing a token whose buyback does nothing.
An approved poolAlso has to be structurally valid: currency0 must be the native currency and the pool must be hookless, or the Treasury constructor reverts with InvalidPool. Accepted pools are fixed at construction, with no way to change them later.

Read the approved set before you build the transaction rather than hardcoding pool keys: approval is admin state and can change.

Initial buy (optional)

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.

TokenCreated event
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
);
amountTokensBoughtThe slippage floor you supplied (minTokenAmount), not the actual swap output. Don't treat it as an exact figure.
stakingAddressAlways equals tokenAddress. Every token is its own staking contract.
dropAddress / treasuryAddressThe zero address if that launch opted out of either.
Reading a user's launched tokens
function getTokensDeployedByUser(address user) external view returns (DeploymentInfo[] memory);
04 / Notes

A few things to keep in mind

Subject to change

Addresses, fees, and thresholds can change with a redeploy. Read them from this page rather than pinning them.

Permissionless

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.