Getting Started
Create a token on the Lens Chain Launchpad
Full Typescript Example
Here's how to integrate directly with the Lens Chain Launchpad contract to create a new token using wagmi/viem. You can copy the full abi for the contract from the bottom of this page.
import { chains } from "@lens-chain/sdk/viem";
import { parseEther } from "viem";
const BonsaiLaunchpadAddress = "0xaB7311a413a39C4F640D152Eec00f70eD3889066";
const BonsaiLaunchpadAbi= { ... }
// wrapped GHO on Lens Chain mainnet
const WGHO_CONTRACT_ADDRESS = "0x6bDc36E20D267Ff0dd6097799f82e78907105e2F";
// NOTE: initialPrice values assume 18 decimals in quote token (WGHO)
const FLAT_THRESHOLD = parseEther("200000000")
const LENS_PRICING_TIERS = {
// 1 WGHO liquidity to graduate
[PricingTier.TEST]: {
initialPrice: "588251339500000000000000000",
flatThreshold: FLAT_THRESHOLD.toString(),
targetPriceMultiplier: 5,
},
// 6000 WGHO liquidity to graduate
[PricingTier.SMALL]: {
initialPrice: "3529508034062500000000000000000",
flatThreshold: FLAT_THRESHOLD.toString(),
targetPriceMultiplier: 5,
},
// 11,000 WGHO liquidity to graduate
[PricingTier.MEDIUM]: {
initialPrice: "6471118034062500000000000000000",
flatThreshold: FLAT_THRESHOLD.toString(),
targetPriceMultiplier: 5,
},
// 21,000 WGHO liquidity to graduate
[PricingTier.LARGE]: {
initialPrice: "12384118034062500000000000000000",
flatThreshold: FLAT_THRESHOLD.toString(),
targetPriceMultiplier: 5,
}
};
type RegistrationTxParams = {
hook: `0x${string}`;
tokenName: string;
tokenSymbol: string;
tokenImage: string;
initialSupply: string;
cliffPercent: number; // bps
vestingDuration: number; // seconds
pricingTier?: PricingTier;
};
export const registerClubTransaction = async (
walletClient, // wagmi wallet client
params: RegistrationTxParams
): Promise<{ clubId?: string, txHash?: string, tokenAddress?: string }> => {
const token = encodeAbi(["string", "string", "string"], [params.tokenName, params.tokenSymbol, params.tokenImage]);
let args = [
params.hook,
token,
params.initialSupply,
zeroAddress,
params.cliffPercent,
params.vestingDuration,
LENS_PRICING_TIERS[params.pricingTier].initialPrice,
LENS_PRICING_TIERS[params.pricingTier].flatThreshold,
LENS_PRICING_TIERS[params.pricingTier].targetPriceMultiplier,
zeroAddress, // optional whitelist module
"0x", // optional whitelist data
WGHO_CONTRACT_ADDRESS, // quote token
];
const hash = await walletClient.writeContract({
address: BonsaiLaunchpadAddress,
abi: BonsaiLaunchpadAbi,
functionName: "registerClub",
args,
chain: chains.mainnet // Lens Chain mainnet
});
console.log(`tx: ${hash}`);
const receipt: TransactionReceipt = await publicClient(chain).waitForTransactionReceipt({ hash });
const event = getEventFromReceipt({
contractAddress: BonsaiLaunchpadAddress,
transactionReceipt: receipt,
abi: BonsaiLaunchpadAbi,
eventName: "RegisteredClub",
});
const res = {
clubId: event.args.clubId.toString(),
tokenAddress: event.args.tokenAddress.toString() as `0x${string}`,
txHash: hash
};
return receipt.status === "success" ? res : {};
};
Guide
Let's walk through the registration params used here:
hook
: Uniswap v4 hook contract address. Since there is currently no v4 deployment on Lens Chain yet this can be the zero addresstokenName
: the name of the token, e.g. "Pepe"tokenSymbol
: the token symbol, e.g. "PEPE"tokenImage
: an image url for the tokeninitialSupply
: the initial amount for the tx sender to buy. Can be up to 80 million tokens (10% of buyable supply). If the value is greater than 0 you will need to approve the contract to spend these tokens firstcliffPercent
: the percent of tokens that will be transferrable on graduation in basis points, e.g. 5000 for 50%vestingDuration
: the number of seconds for remaining token balances to vest linearly over after graduation, e.g. 3600 for 1 hourpricingTier
: The pricing parameters for the Launchpad. This determines the starting price for the token in Wrapped GHO, the number of tokens that will be sold at a flat price before the bonding curve kicks in and the ending price as a multiplier of the starting price. The tiers listed in the code above are the tiers used in the Bonsai app but you can use any values you want.
Whitelist module
You can include a whitelist module to only allow addresses that fulfill some requirement to be able to buy on the Launchpad. This is purely optional, the above example does not include a module.
The whitelist module interface is defined as such:
interface IWhitelistModule {
function createWhitelist(uint256 clubId, bytes calldata data) external;
function isWhitelisted(address user, uint256 clubId) external view returns (bool);
}
For example you could create a collect whitelist module that requires buyers to collect a certain post before they can buy the token:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {IWhitelistModule} from "../interfaces/IWhitelistModule.sol";
contract CollectWhitelistModule is IWhitelistModule {
event WhitelistCreated(uint256 indexed clubId, address indexed collectContract, uint256 expiresAt);
struct Whitelist {
address collectContract; // contract address of the collect
uint256 expiresAt; // timestamp when the whitelist expires and becomes open to all
}
mapping(uint256 => Whitelist) public whitelists;
function createWhitelist(uint256 clubId, bytes calldata data) external {
(address collectContract, uint256 timePeriod) = abi.decode(data, (address, uint256));
uint256 expiresAt = block.timestamp + timePeriod;
whitelists[clubId] = Whitelist(collectContract, expiresAt);
emit WhitelistCreated(clubId, collectContract, expiresAt);
}
function isWhitelisted(address user, uint256 clubId) external view returns (bool) {
Whitelist storage whitelist = whitelists[clubId];
if (whitelist.collectContract == address(0) || whitelist.expiresAt == 0) return false;
if (block.timestamp > whitelist.expiresAt || IERC721(whitelist.collectContract).balanceOf(user) > 0) {
return true;
}
return false;
}
}
Linking your token for display on the Bonsai app
If you want to link your token to a Lens post & account, follow the guide here:
Link your token to a Lens Post & AccountInteract with the Launchpad contract using AI (on Nebula)

Last updated