Integrate
Pair your launchpad against packs
Three steps. Your launch contracts treat a pack as an ordinary ERC-20 quote asset, so nothing about your token, your pool or your fee model has to change.
1. Accept any pack as a quote asset
Ask the registry instead of keeping your own allow-list. Any pack that anyone registers then works on your launchpad the moment it exists, with no admin step from you and none from us.
interface IPackRegistry {
function isPack(address pack) external view returns (bool);
}
address public packRegistry;
function _quoteIsAllowed(address quote) internal view returns (bool) {
return IPackRegistry(packRegistry).isPack(quote);
}If your factory caches quote metadata, cache it on first use rather than in an owner-only registration call — that is what turns a new pack into a usable pair without a transaction from you.
2. Price the opening market cap in packs
One endpoint gives you the USD value of a single pack unit. Most launch factories want that number signed for their own EIP-712 domain: the NAV is data from us, the signature over it is yours, made with your own signer key.
curl "https://lnchr.io/api/nav?pack=0xPACK"
{
"pack": "0xPACK",
"symbol": "AMN",
"navUsd": 1.0241,
"navUsdWei": "1024100000000000000",
"stocks": ["0x...", "0x...", "0x..."],
"composition": ["...", "...", "..."],
"at": 1789200000
}You can also read it on chain from PackLens.navUsdg(pack), which returns the value of one unit in USDG with no server in the path.
3. Route buys through the pack pool
A buy with ETH is two hops in one Uniswap v4 unlock: the pack pool first, your launch pool second. Selling runs the same road backwards. If you only need the pack leg — buying or selling packs themselves — PackRouter already does it.
import { lnchr } from "@lnchr/sdk";
const sdk = lnchr();
const buy = sdk.buildBuyWithEth({ pack, minOut: 0n, value: parseEther("0.1") });
const hash = await walletClient.writeContract(buy);PoolKey memory packKey = IPackPools(packHook).poolKey(pack, weth);
PoolKey[] memory hops = new PoolKey[](2);
hops[0] = packKey;
hops[1] = launchKey;Letting people register new packs
Optional, and two calls. Ask for a signed price set, then register. The signature fixes the quantities so a unit opens at $1.00 and expires after three minutes. Nothing about it is permissioned — the same call works from your app, our docs or a script.
const { registered, pack, ticker } = await sdk.predictPack(stocks);
if (!registered) {
const tx = await sdk.buildRegisterPack(stocks);
await walletClient.writeContract(tx);
}Four things that will bite you
- Do not redeploy the pack contracts. A pack must have one address per chain. A second registry splits holders, charts and every integration built on top.
- Do not price a pack from pool reserves. There are none. Use
PackLens.navUsdgor the NAV endpoint. - Do not add liquidity to a pack pool. The hook rejects it. Depth comes from the underlying stock markets.
- Do not key anything on the ticker. Tickers collide by design. Key on the pack address.
Contract addresses and ABIs are on Contracts, and every helper is listed on SDK.