Documentation
Indexing
Index the BondingCurveManager address only. Every launch and fill is logged there, so a single subscription covers discovery and trade history.
Recommended flow
- Watch or backfill
TokenCreatedto register each launch (token,creator,name,symbol,uri). - Persist
uri(or fetch CDN metadata) for display name, symbol, and logo. - Subscribe to
Tradefiltered bytokenfor fills, volume, and spot updates. - Optionally listen for
CurveCompletedto mark graduation and locked liquidity.
TokenCreated
Emitted once when a token is launched. Treat this as the canonical discovery event. The uri field is the ERC-1046 metadata URL (CDN path https://cdn.arklis.app/token/{token}/metadata.json).
TokenCreatedeventevent TokenCreated(
address indexed token,
address indexed creator,
string name,
string symbol,
string uri,
uint256 virtualEth,
uint256 virtualToken
)token— ERC-20 address (indexed topic)creator— launch creator (indexed)name,symbol— on-chain strings at createuri— metadata JSON URLvirtualEth,virtualToken— initial virtual reserves
Trade
Emitted on every buy and sell. isBuy is indexed so you can filter buys and sells with topics.
Tradeeventevent Trade(
address indexed token,
address indexed trader,
bool indexed isBuy,
uint256 ethAmount,
uint256 tokenAmount,
uint256 feeEth,
uint256 reserveEth,
uint256 soldTokens,
uint256 spotPriceWei
)ethAmount— gross ETH for the fill (wei)tokenAmount— token amount transferred (6 decimals, raw)feeEth— protocol trade fee taken (wei)isBuy—truefor buy,falsefor sellspotPriceWei— spot after the fill (wei per whole token unit)
CurveCompleted
Emitted when a token reaches its graduation threshold. After this event, remaining protocol liquidity stays permanently locked in the Manager. No LP tokens are minted and reserves cannot be withdrawn.
CurveCompletedeventevent CurveCompleted(address indexed token)Example
viem getLogs and watchts
import {
createPublicClient,
createWalletClient,
http,
parseAbi,
parseAbiItem,
zeroAddress,
type Address,
} from "viem";
import { privateKeyToAccount } from "viem/accounts";
/** Arklis BondingCurveManager — Robinhood Chain (4663) */
export const MANAGER = "0x8c0CB9498fE0dCC9F5405e99A17C01579c7C6066" as const;
export const CHAIN_ID = 4663 as const;
export const FEE_BPS_TOTAL = 125n;
export const BPS_DENOM = 10000n;
export const TOKEN_DECIMALS = 6;
const rpcUrl = process.env.RPC_URL!;
export const publicClient = createPublicClient({
chain: {
id: CHAIN_ID,
name: "Robinhood Chain",
nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 },
rpcUrls: { default: { http: [rpcUrl] } },
},
transport: http(rpcUrl),
});
const tokenCreatedEvent = parseAbiItem(
"event TokenCreated(address indexed token, address indexed creator, string name, string symbol, string uri, uint256 virtualEth, uint256 virtualToken)",
);
const tradeEvent = parseAbiItem(
"event Trade(address indexed token, address indexed trader, bool indexed isBuy, uint256 ethAmount, uint256 tokenAmount, uint256 feeEth, uint256 reserveEth, uint256 soldTokens, uint256 spotPriceWei)",
);
/** Index new launches from the Manager only. */
export async function getLaunches(fromBlock: bigint, toBlock: bigint) {
return publicClient.getLogs({
address: MANAGER,
event: tokenCreatedEvent,
fromBlock,
toBlock,
});
}
/** Index trades. Pass token to filter one launch; omit for all fills. */
export async function getTrades(
fromBlock: bigint,
toBlock: bigint,
token?: Address,
) {
return publicClient.getLogs({
address: MANAGER,
event: tradeEvent,
args: token ? { token } : undefined,
fromBlock,
toBlock,
});
}
export function watchLaunches(
onLaunch: (args: {
token: Address;
creator: Address;
name: string;
symbol: string;
uri: string;
}) => void,
) {
return publicClient.watchContractEvent({
address: MANAGER,
abi: parseAbi([
"event TokenCreated(address indexed token, address indexed creator, string name, string symbol, string uri, uint256 virtualEth, uint256 virtualToken)",
]),
eventName: "TokenCreated",
onLogs: (logs) => {
for (const log of logs) {
onLaunch({
token: log.args.token!,
creator: log.args.creator!,
name: log.args.name!,
symbol: log.args.symbol!,
uri: log.args.uri!,
});
}
},
});
}Coming soon