Skip to main content Início Criadores qhkm zeptoclaw-skills clanker
clanker Deploy ERC20 tokens on Base, Ethereum, Arbitrum, and other EVM chains using the Clanker SDK. Use when the user wants to deploy a new token, create a memecoin, set up token vesting, configure airdrops, manage token rewards, claim LP fees, or update token metadata. Supports V4 deployment with vaults, airdrops, dev buys, custom market caps, vanity addresses, and multi-chain deployment.
Ir para a instalação Skills Marketplace Descubra e explore skills de IA criadas pela comunidade.
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Copiar promptMostrar detalhes do prompt Um comando direto ignora o prompt de revisão. Verifique a origem antes de executá-lo.
npx skills add https://github.com/qhkm/zeptoclaw-skills --skill clankerO comando permanece em uma só linha. Role horizontalmente para revisá-lo antes de copiar.
Prefere uma cópia local? Baixe os arquivos disponíveis atualmente no SkillsMP.
Baixar Zip Baixando... Mais deste repositório Give your agent a standalone on-chain wallet for gasless trades, funding, and autonomous x402 M2M payments.
AI-powered crypto trading agent and LLM gateway via natural language. Use when the user wants to trade crypto, check portfolio balances, view token prices, transfer crypto, manage NFTs, use leverage, bet on Polymarket, deploy tokens, set up automated trading, sign and submit raw transactions, or access LLM models through the Bankr LLM gateway funded by your Bankr wallet. Supports Base, Ethereum, Polygon, Solana, and Unichain.
Get swap quotes, check approvals, execute swaps, and generate deep links using the Uniswap Trading API.
name clanker version 1.0.0 description Deploy ERC20 tokens on Base, Ethereum, Arbitrum, and other EVM chains using the Clanker SDK. Use when the user wants to deploy a new token, create a memecoin, set up token vesting, configure airdrops, manage token rewards, claim LP fees, or update token metadata. Supports V4 deployment with vaults, airdrops, dev buys, custom market caps, vanity addresses, and multi-chain deployment. author BankrBot license MIT tags ["crypto","defi","token-deployment","base"] env_needed [{"name":"PRIVATE_KEY","description":"Private key for the EVM wallet deploying the tokens (must start with 0x)","required":true}] metadata {"zeptoclaw":{"emoji":"🚀","requires":{"anyBins":["npm","yarn","pnpm"]}}}
Clanker SDK
Deploy production-ready ERC20 tokens with built-in liquidity pools using the official Clanker TypeScript SDK.
🚨 Financial Safety Guardrails
This skill enables high-risk financial operations (token deployment requires gas, dev buys require funds, and liquidity parameters are immutable). You MUST adhere to the following safety rules:
Always confirm with the user before executing the deployment script.
Display all parameters clearly before execution: Token Name, Symbol, Total Supply, Vault allocations, Dev buy amounts, and target chain.
Double-check dev buy amounts: Do NOT execute large dev buys without explicit double-confirmation from the user.
Warn users about irreversibility: Smart contract deployments are permanent and cannot be deleted once broadcast to the blockchain.
Overview
Clanker is a token deployment protocol that creates ERC20 tokens with Uniswap V4 liquidity pools in a single transaction. The SDK provides a TypeScript interface for deploying tokens with advanced features like vesting, airdrops, and customizable reward distribution.
Quick Start
Installation
npm install clanker-sdk viem
yarn add clanker-sdk viem
pnpm add clanker-sdk viem
Environment Setup
Create a .env file with your private key:
PRIVATE_KEY=0x...your_private_key_here
Basic Token Deployment
import { Clanker } from 'clanker-sdk' ;
import { createPublicClient, createWalletClient, http, type PublicClient } from 'viem' ;
import { privateKeyToAccount } from 'viem/accounts' ;
import { base } from 'viem/chains' ;
const PRIVATE_KEY = process.env . ;
account = ( );
publicClient = ({
: base,
: (),
}) ;
wallet = ({
account,
: base,
: (),
});
clanker = ({ wallet, publicClient });
{ txHash, waitForTransaction, error } = clanker. ({
: ,
: ,
: ,
: account. ,
: {
: ,
},
: {
: ,
},
: ,
});
(error) error;
{ : tokenAddress } = ();
. ( , tokenAddress);
Ocupações relacionadas SOC
Baseado na classificação ocupacional SOC
PRIVATE_KEY
as
`0x${string } `
const
privateKeyToAccount
PRIVATE_KEY
const
createPublicClient
chain
transport
http
as
PublicClient
const
createWalletClient
chain
transport
http
const
new
Clanker
const
await
deploy
name
'My Token'
symbol
'TKN'
image
'ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi'
tokenAdmin
address
metadata
description
'My awesome token'
context
interface
'Clanker SDK'
vanity
true
if
throw
const
address
await
waitForTransaction
console
log
'Token deployed at:'
Core Capabilities
1. Token Deployment Deploy tokens with full customization including metadata, social links, and pool configuration.
Token name, symbol, and image (IPFS)
Description and social media links
Vanity address generation
Custom pool configurations
Reference: the Advanced Reference Guide below (deployment)
2. Vault (Token Vesting) Lock a percentage of tokens with lockup and vesting periods:
vault : {
percentage : 10 ,
lockupDuration : 2592000 ,
vestingDuration : 2592000 ,
recipient : account.address ,
}
Reference: the Advanced Reference Guide below (vesting)
3. Airdrops Distribute tokens to multiple addresses using Merkle tree proofs:
import { createAirdrop, registerAirdrop } from 'clanker-sdk/v4/extensions' ;
const { tree, airdrop } = createAirdrop ([
{ account : '0x...' , amount : 200_000_000 },
{ account : '0x...' , amount : 50_000_000 },
]);
airdrop : {
...airdrop,
lockupDuration : 86_400 ,
vestingDuration : 86_400 ,
}
Reference: the Advanced Reference Guide below (airdrops)
4. Rewards Configuration Configure trading fee distribution:
rewards : {
recipients : [
{
recipient : account.address ,
admin : account.address ,
bps : 5000 ,
token : 'Both' ,
},
{
recipient : '0x...' ,
admin : '0x...' ,
bps : 5000 ,
token : 'Both' ,
},
],
}
Token Type Options Choose which tokens each recipient receives from trading fees:
Token Type Description 'Clanker'Receive only the deployed token 'Paired'Receive only the paired token (e.g., WETH) 'Both'Receive both tokens
Default Bankr Interface Fee When deploying via Bankr, use this default rewards configuration with 20% interface fee:
const BANKR_INTERFACE_ADDRESS = '0xF60633D02690e2A15A54AB919925F3d038Df163e' ;
rewards : {
recipients : [
{
recipient : account.address ,
admin : account.address ,
bps : 8000 ,
token : 'Paired' ,
},
{
recipient : BANKR_INTERFACE_ADDRESS ,
admin : BANKR_INTERFACE_ADDRESS ,
bps : 2000 ,
token : 'Paired' ,
},
],
}
Reference: the Advanced Reference Guide below (rewards)
5. Dev Buy Include an initial token purchase in the deployment:
devBuy : {
ethAmount : 0.1 ,
recipient : account.address ,
}
6. Custom Market Cap Set initial token price/market cap:
import { getTickFromMarketCap } from 'clanker-sdk' ;
const customPool = getTickFromMarketCap (5 );
pool : {
...customPool,
positions : [
{
tickLower : customPool.tickIfToken0IsClanker ,
tickUpper : -120000 ,
positionBps : 10_000 ,
},
],
}
Reference: the Advanced Reference Guide below (pool-config)
7. Anti-Sniper Protection Configure fee decay to protect against snipers:
sniperFees : {
startingFee : 666_777 ,
endingFee : 41_673 ,
secondsToDecay : 15 ,
}
Contract Limits & Constants Parameter Value Notes Token Supply 100 billion Fixed at 100,000,000,000 with 18 decimals Max Extension BPS 9000 (90%) Max tokens to extensions, min 10% to LP Max Extensions 10 Maximum number of extensions per deployment Vault Min Lockup 7 days Minimum lockup duration for vesting Airdrop Min Lockup 1 day Minimum lockup duration for airdrops Max LP Fee 10% Normal trading fee cap Max Sniper Fee 80% Maximum MEV/sniper protection fee Sniper Fee Decay 2 minutes max Maximum time for sniper fee decay Max Reward Recipients 7 Maximum fee distribution recipients Max LP Positions 7 Maximum liquidity positions
Supported Chains Chain Chain ID Native Token Status Base 8453 ETH ✅ Full support Ethereum 1 ETH ✅ Full support Arbitrum 42161 ETH ✅ Full support Unichain - ETH ✅ Full support Monad - MON ✅ Static fees only
Post-Deployment Operations
Claim Vaulted Tokens const claimable = await clanker.getVaultClaimableAmount ({ token : TOKEN_ADDRESS });
if (claimable > 0n ) {
const { txHash } = await clanker.claimVaultedTokens ({ token : TOKEN_ADDRESS });
}
Collect Trading Rewards
const availableFees = await clanker.availableRewards ({
token : TOKEN_ADDRESS ,
rewardRecipient : FEE_OWNER_ADDRESS ,
});
const { txHash } = await clanker.claimRewards ({
token : TOKEN_ADDRESS ,
rewardRecipient : FEE_OWNER_ADDRESS ,
});
Update Token Metadata const metadata = JSON .stringify ({
description : 'Updated description' ,
socialMediaUrls : [
{ platform : 'twitter' , url : 'https://twitter.com/mytoken' },
{ platform : 'telegram' , url : 'https://t.me/mytoken' },
],
});
const { txHash } = await clanker.updateMetadata ({
token : TOKEN_ADDRESS ,
metadata,
});
Update Token Image const { txHash } = await clanker.updateImage ({
token : TOKEN_ADDRESS ,
image : 'ipfs://new_image_hash' ,
});
Common Workflows
Simple Memecoin Launch
Prepare token image (upload to IPFS)
Deploy with basic config (name, symbol, image)
Enable vanity address for memorable contract
Share contract address
Community Token with Airdrop
Compile airdrop recipient list
Create Merkle tree with createAirdrop()
Deploy token with airdrop extension
Register airdrop with Clanker service
Share claim instructions
Creator Token with Vesting
Deploy with vault configuration
Set lockup period (cliff)
Set vesting duration
Claim tokens as they vest
Full Deployment Config
const BANKR_INTERFACE_ADDRESS = '0xF60633D02690e2A15A54AB919925F3d038Df163e' ;
const tokenConfig = {
chainId : 8453 ,
name : 'My Token' ,
symbol : 'TKN' ,
image : 'ipfs://...' ,
tokenAdmin : account.address ,
metadata : {
description : 'Token description' ,
socialMediaUrls : [
{ platform : 'twitter' , url : '...' },
{ platform : 'telegram' , url : '...' },
],
},
context : {
interface : 'Bankr' ,
platform : 'farcaster' ,
messageId : '' ,
id : '' ,
},
vault : {
percentage : 10 ,
lockupDuration : 2592000 ,
vestingDuration : 2592000 ,
recipient : account.address ,
},
devBuy : {
ethAmount : 0 ,
recipient : account.address ,
},
rewards : {
recipients : [
{
recipient : account.address ,
admin : account.address ,
bps : 8000 ,
token : 'Paired' ,
},
{
recipient : BANKR_INTERFACE_ADDRESS ,
admin : BANKR_INTERFACE_ADDRESS ,
bps : 2000 ,
token : 'Paired' ,
},
],
},
pool : {
pairedToken : '0x4200000000000000000000000000000000000006' ,
positions : 'Standard' ,
},
fees : 'StaticBasic' ,
vanity : true ,
sniperFees : {
startingFee : 666_777 ,
endingFee : 41_673 ,
secondsToDecay : 15 ,
},
};
Best Practices
Security
Never expose private keys - Use environment variables
Test on testnet first - Verify configs before mainnet
Simulate transactions - Use *Simulate methods before execution
Verify addresses - Double-check all recipient addresses
Token Design
Choose meaningful names - Clear, memorable token identity
Use quality images - High-res, appropriate IPFS images
Configure vesting wisely - Align with project timeline
Gas Optimization
Use Base or Arbitrum - Lower gas fees
Batch operations - Combine when possible
Monitor gas prices - Deploy during low-traffic periods
Troubleshooting
Common Issues
"Missing PRIVATE_KEY" - Set environment variable
"Insufficient balance" - Fund wallet with native token
"Transaction reverted" - Check parameters, simulate first
"Invalid image" - Ensure IPFS hash is accessible
Debug Steps
Check wallet balance
Verify chain configuration
Use simulation methods
Check transaction on block explorer
Review error message details
Resources
💡 Pro Tip : Always use the vanity: true option for memorable contract addresses.
⚠️ Security : Never commit private keys. Use .env files and add them to .gitignore.
🚀 Quick Win : Start with the simple deployment example, then add features like vesting and rewards as needed.
📚 Advanced Reference Guide
The following sections were inlined from the former references/ directory.
📖 Reference: airdrops.md
Airdrops Distribute tokens to multiple addresses using Merkle tree proofs with the Clanker airdrop extension.
Overview Airdrops allow you to allocate tokens to specific addresses during deployment. Key features:
Merkle tree verification - Efficient on-chain proof verification
Lockup/vesting - Control when tokens become claimable
Clanker service - Optional proof storage and generation
Create an Airdrop import { createAirdrop, registerAirdrop } from 'clanker-sdk/v4/extensions' ;
const { tree, airdrop } = createAirdrop ([
{
account : '0x308112D06027Cd838627b94dDFC16ea6B4D90004' ,
amount : 200_000_000 ,
},
{
account : '0x1eaf444ebDf6495C57aD52A04C61521bBf564ace' ,
amount : 50_000_000 ,
},
{
account : '0x04F6ef12a8B6c2346C8505eE4Cff71C43D2dd825' ,
amount : 10_000_000 ,
},
]);
Deploy with Airdrop Include the airdrop in your token deployment:
import { Clanker } from 'clanker-sdk' ;
import { createAirdrop } from 'clanker-sdk/v4/extensions' ;
const { tree, airdrop } = createAirdrop ([
{ account : '0x...' , amount : 200_000_000 },
{ account : '0x...' , amount : 50_000_000 },
]);
const { txHash, waitForTransaction, error } = await clanker.deploy ({
name : 'Airdrop Token' ,
symbol : 'DROP' ,
image : 'ipfs://...' ,
tokenAdmin : account.address ,
metadata : {
description : 'Token with an airdrop' ,
},
context : {
interface : 'Clanker SDK' ,
},
airdrop : {
...airdrop,
lockupDuration : 86_400 ,
vestingDuration : 86_400 ,
},
vanity : true ,
});
if (error) throw error;
const { address } = await waitForTransaction ();
console .log ('Token deployed at:' , address);
Register Airdrop with Clanker Service Store the Merkle tree with Clanker's service for easy proof generation:
import { registerAirdrop, fetchAirdropProofs } from 'clanker-sdk/v4/extensions' ;
import { sleep } from 'bun' ;
await sleep (10_000 );
await registerAirdrop (tokenAddress, tree);
console .log ('Airdrop registered!' );
Fetch Airdrop Proofs Get proofs for a specific address:
import { fetchAirdropProofs } from 'clanker-sdk/v4/extensions' ;
const { proofs } = await fetchAirdropProofs (
tokenAddress,
'0x308112D06027Cd838627b94dDFC16ea6B4D90004'
);
console .log ('Proofs:' , proofs);
Claim Airdrop Tokens Build and execute a claim transaction:
import { getClaimAirdropTransaction } from 'clanker-sdk/v4/extensions' ;
const { proof, entry } = proofs[0 ];
const tx = getClaimAirdropTransaction ({
chainId : base.id ,
token : tokenAddress,
recipient : entry.account ,
amount : entry.amount ,
proof,
});
const hash = await wallet.sendTransaction (tx);
Self-Managed Tree Storage If you don't want to use the Clanker service, store and manage the tree yourself:
import { StandardMerkleTree } from '@openzeppelin/merkle-tree' ;
import fs from 'fs' ;
const { tree, airdrop } = createAirdrop ([...]);
fs.writeFileSync ('merkle-tree.json' , JSON .stringify (tree.dump ()));
const loadedTree = StandardMerkleTree .load (
JSON .parse (fs.readFileSync ('merkle-tree.json' , 'utf8' ))
);
Contract Limits From the Solidity contracts:
Minimum Lockup Duration : 1 day (86,400 seconds) - enforced on-chain
Maximum Extension BPS : 9000 (90% of supply can go to extensions total)
airdrop : {
...airdrop,
lockupDuration : 86_400 ,
vestingDuration : 0 ,
}
Note : Unlike vault (7 days min), airdrop only requires 1 day minimum lockup.
Airdrop with Extended Vesting For gradual distribution:
const THIRTY_DAYS = 2592000 ;
airdrop : {
...airdrop,
lockupDuration : THIRTY_DAYS ,
vestingDuration : THIRTY_DAYS * 3 ,
}
Complete Airdrop Workflow import { sleep } from 'bun' ;
import { createPublicClient, createWalletClient, http, type PublicClient } from 'viem' ;
import { privateKeyToAccount } from 'viem/accounts' ;
import { base } from 'viem/chains' ;
import {
createAirdrop,
fetchAirdropProofs,
getClaimAirdropTransaction,
registerAirdrop,
} from 'clanker-sdk/v4/extensions' ;
import { Clanker } from 'clanker-sdk/v4' ;
const PRIVATE_KEY = process.env .PRIVATE_KEY as `0x${string } ` ;
const account = privateKeyToAccount (PRIVATE_KEY );
const publicClient = createPublicClient ({ chain : base, transport : http () }) as PublicClient ;
const wallet = createWalletClient ({ account, chain : base, transport : http () });
const clanker = new Clanker ({ publicClient, wallet });
const { tree, airdrop } = createAirdrop ([
{ account : '0x308112D06027Cd838627b94dDFC16ea6B4D90004' , amount : 200_000_000 },
{ account : '0x1eaf444ebDf6495C57aD52A04C61521bBf564ace' , amount : 50_000_000 },
{ account : '0x04F6ef12a8B6c2346C8505eE4Cff71C43D2dd825' , amount : 10_000_000 },
]);
const { txHash, waitForTransaction, error } = await clanker.deploy ({
name : 'Airdrop Token' ,
symbol : 'DROP' ,
image : 'ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi' ,
tokenAdmin : account.address ,
metadata : { description : 'Token with an airdrop' },
context : { interface : 'Clanker SDK' },
airdrop : {
...airdrop,
lockupDuration : 86_400 ,
vestingDuration : 86_400 ,
},
vanity : true ,
});
if (error) throw error;
const { address, error : txError } = await waitForTransaction ();
if (txError) throw txError;
console .log (`Token deployed at: ${address} ` );
console .log ('Waiting for indexing...' );
await sleep (10_000 );
await registerAirdrop (address, tree);
console .log ('Airdrop registered!' );
const { proofs } = await fetchAirdropProofs (
address,
'0x308112D06027Cd838627b94dDFC16ea6B4D90004'
);
console .log ('Proofs ready for claiming:' , proofs);
Best Practices
Verify recipient addresses - Double-check all addresses before deployment
Test with small amounts - Verify the flow on testnet first
Secure tree storage - Back up the Merkle tree if self-managing
Reasonable lockup - Balance between anti-dump and user experience
Communicate claim process - Provide clear instructions to recipients
📖 Reference: deployment.md
Token Deployment Complete guide to deploying tokens with the Clanker SDK.
Simple Deployment The minimal configuration for deploying a token:
import { Clanker } from 'clanker-sdk' ;
import { createPublicClient, createWalletClient, http, type PublicClient } from 'viem' ;
import { privateKeyToAccount } from 'viem/accounts' ;
import { base } from 'viem/chains' ;
const PRIVATE_KEY = process.env .PRIVATE_KEY as `0x${string } ` ;
const account = privateKeyToAccount (PRIVATE_KEY );
const publicClient = createPublicClient ({
chain : base,
transport : http (),
}) as PublicClient ;
const wallet = createWalletClient ({
account,
chain : base,
transport : http (),
});
const clanker = new Clanker ({ wallet, publicClient });
const { txHash, waitForTransaction, error } = await clanker.deploy ({
name : 'My Token' ,
symbol : 'TKN' ,
image : 'ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi' ,
tokenAdmin : account.address ,
chainId : base.id ,
metadata : {
description : 'My really cool token' ,
},
context : {
interface : 'Clanker SDK' ,
},
vanity : true ,
});
if (error) throw error;
console .log (`Deploying... ${base.blockExplorers.default .url} /tx/${txHash} ` );
const { address : tokenAddress } = await waitForTransaction ();
console .log (`Done! ${base.blockExplorers.default .url} /address/${tokenAddress} ` );
Multi-Chain Deployment Deploy to different chains by changing the chain configuration:
import { base, mainnet, arbitrum, unichain } from 'viem/chains' ;
const RPC_URLS : Record <number , string | undefined > = {
[mainnet.id ]: process.env .RPC_URL_MAINNET ,
[base.id ]: process.env .RPC_URL_BASE ,
[arbitrum.id ]: process.env .RPC_URL_ARBITRUM ,
[unichain.id ]: process.env .RPC_URL_UNICHAIN ,
};
const CHAIN = base;
const publicClient = createPublicClient ({
chain : CHAIN ,
transport : http (RPC_URLS [CHAIN .id ]),
}) as PublicClient ;
const wallet = createWalletClient ({
account,
chain : CHAIN ,
transport : http (RPC_URLS [CHAIN .id ]),
});
const clanker = new Clanker ({ wallet, publicClient });
const { txHash, waitForTransaction, error } = await clanker.deploy ({
chainId : CHAIN .id ,
name : 'My Token' ,
symbol : 'TKN' ,
});
Token Metadata Configure rich metadata for your token:
metadata : {
description : 'Token with custom configuration including vesting and rewards' ,
socialMediaUrls : [
{ platform : 'twitter' , url : 'https://twitter.com/mytoken' },
{ platform : 'telegram' , url : 'https://t.me/mytoken' },
{ platform : 'discord' , url : 'https://discord.gg/mytoken' },
],
auditUrls : ['https://example.com/audit' ],
}
Context Configuration Track deployment source and social platform info:
context : {
interface : 'Clanker SDK' ,
platform : 'farcaster' ,
messageId : '' ,
id : '' ,
}
Vanity Addresses Enable vanity address generation for memorable contract addresses:
const { txHash, waitForTransaction, error } = await clanker.deploy ({
vanity : true ,
});
Full Configuration Example
const BANKR_INTERFACE_ADDRESS = '0xF60633D02690e2A15A54AB919925F3d038Df163e' ;
const { txHash, waitForTransaction, error } = await clanker.deploy ({
chainId : base.id ,
name : 'My Token' ,
symbol : 'TKN' ,
image : 'ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi' ,
tokenAdmin : account.address ,
metadata : {
description : 'Token with custom configuration including vesting and rewards' ,
socialMediaUrls : [
{ platform : 'twitter' , url : 'https://twitter.com/mytoken' },
{ platform : 'telegram' , url : 'https://t.me/mytoken' },
],
},
context : {
interface : 'Bankr' ,
platform : 'farcaster' ,
messageId : '' ,
id : '' ,
},
vault : {
percentage : 10 ,
lockupDuration : 2592000 ,
vestingDuration : 2592000 ,
recipient : account.address ,
},
devBuy : {
ethAmount : 0 ,
recipient : account.address ,
},
rewards : {
recipients : [
{
recipient : account.address ,
admin : account.address ,
bps : 8000 ,
token : 'Paired' ,
},
{
recipient : BANKR_INTERFACE_ADDRESS ,
admin : BANKR_INTERFACE_ADDRESS ,
bps : 2000 ,
token : 'Paired' ,
},
],
},
pool : {
pairedToken : '0x4200000000000000000000000000000000000006' ,
positions : 'Standard' ,
},
fees : 'StaticBasic' ,
vanity : true ,
sniperFees : {
startingFee : 666_777 ,
endingFee : 41_673 ,
secondsToDecay : 15 ,
},
});
Deploy with Custom Salt Use a specific salt for deterministic address generation:
import { zeroHash } from 'viem' ;
const { txHash, waitForTransaction, error } = await clanker.deploy ({
salt : zeroHash,
});
Deploy with USDC Pair Create a token paired with USDC instead of WETH:
const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' ;
const { txHash, waitForTransaction, error } = await clanker.deploy ({
pool : {
pairedToken : USDC_BASE ,
positions : 'Standard' ,
},
});
Deploy with 20 ETH Initial Liquidity Configure larger initial market cap:
import { getTickFromMarketCap } from 'clanker-sdk' ;
const customPool = getTickFromMarketCap (20 );
const { txHash, waitForTransaction, error } = await clanker.deploy ({
pool : {
...customPool,
positions : [
{
tickLower : customPool.tickIfToken0IsClanker ,
tickUpper : -120000 ,
positionBps : 10_000 ,
},
],
},
});
Error Handling Always handle deployment errors:
const { txHash, waitForTransaction, error } = await clanker.deploy (config);
if (error) {
console .error ('Deployment failed:' , error.message );
process.exit (1 );
}
console .log (`Transaction: ${txHash} ` );
const { address, error : txError } = await waitForTransaction ();
if (txError) {
console .error ('Transaction failed:' , txError.message );
process.exit (1 );
}
console .log ('Token deployed at:' , address);
Simulation Before Deployment Test deployment without executing:
try {
await clanker.deploySimulate (config);
console .log ('Simulation successful' );
} catch (error) {
console .error ('Simulation failed:' , error);
}
📖 Reference: pool-config.md
Pool Configuration Configure Uniswap V4 liquidity pool settings for your Clanker token.
Overview Clanker tokens are deployed with Uniswap V4 liquidity pools. You can customize:
Paired token - WETH, USDC, or other tokens
Initial market cap - Starting price/liquidity
Pool positions - Liquidity distribution
Fee structure - Static or dynamic fees
Sniper protection - Fee decay for early trades
Default Pool Configuration By default, tokens are paired with WETH using standard positions:
const { txHash, waitForTransaction, error } = await clanker.deploy ({
name : 'My Token' ,
symbol : 'TKN' ,
image : 'ipfs://...' ,
tokenAdmin : account.address ,
});
Paired Token Options
WETH (Default) import { WETH_ADDRESSES } from 'clanker-sdk/constants' ;
pool : {
pairedToken : WETH_ADDRESSES [base.id ],
positions : 'Standard' ,
}
USDC const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' ;
pool : {
pairedToken : USDC_BASE ,
positions : 'Standard' ,
}
Pool Positions Choose from preset position configurations:
import { POOL_POSITIONS } from 'clanker-sdk/constants' ;
pool : {
pairedToken : WETH_ADDRESSES [base.id ],
positions : POOL_POSITIONS .Standard ,
positions : POOL_POSITIONS .Project ,
}
Custom Market Cap Set a specific initial market cap:
import { getTickFromMarketCap } from 'clanker-sdk' ;
const customPool = getTickFromMarketCap (5 );
pool : {
...customPool,
positions : [
{
tickLower : customPool.tickIfToken0IsClanker ,
tickUpper : -120000 ,
positionBps : 10_000 ,
},
],
}
Market Cap Examples
const pool5ETH = getTickFromMarketCap (5 );
const pool10ETH = getTickFromMarketCap (10 );
const pool20ETH = getTickFromMarketCap (20 );
Fee Configurations Choose between static and dynamic fee structures:
import { FEE_CONFIGS } from 'clanker-sdk/constants' ;
fees : FEE_CONFIGS .StaticBasic ,
fees : FEE_CONFIGS .Dynamic3 ,
Note: Monad chain only supports static fees (FEE_CONFIGS.StaticBasic).
Sniper Protection Configure fee decay to protect against snipers:
sniperFees : {
startingFee : 666_777 ,
endingFee : 41_673 ,
secondsToDecay : 15 ,
}
Contract Limits From the Solidity contracts:
Parameter Limit Notes MAX_MEV_LP_FEE 800,000 (80%) Maximum starting fee MAX_LP_FEE 100,000 (10%) Normal LP fee cap MAX_MEV_MODULE_DELAY 120 seconds Maximum decay time Fee Denominator 1,000,000 100% = 1,000,000
startingFee cannot exceed 800,000 (80%)
secondsToDecay cannot exceed 120 seconds (2 minutes)
startingFee must be greater than endingFee
How Sniper Fees Work
Trade immediately after deployment → Pay up to 80% fee
Fee decays parabolically over the decay period
After decay period → Normal LP fee applies
Aggressive Sniper Protection sniperFees : {
startingFee : 800_000 ,
endingFee : 30_000 ,
secondsToDecay : 120 ,
}
Moderate Sniper Protection sniperFees : {
startingFee : 666_777 ,
endingFee : 41_673 ,
secondsToDecay : 15 ,
}
Minimal Sniper Protection sniperFees : {
startingFee : 100_000 ,
endingFee : 30_000 ,
secondsToDecay : 5 ,
}
Full Pool Configuration Example import { getTickFromMarketCap } from 'clanker-sdk' ;
import { FEE_CONFIGS , WETH_ADDRESSES } from 'clanker-sdk/constants' ;
import { base } from 'viem/chains' ;
const customPool = getTickFromMarketCap (10 );
const { txHash, waitForTransaction, error } = await clanker.deploy ({
name : 'Custom Pool Token' ,
symbol : 'CPT' ,
image : 'ipfs://...' ,
tokenAdmin : account.address ,
pool : {
pairedToken : WETH_ADDRESSES [base.id ],
...customPool,
positions : [
{
tickLower : customPool.tickIfToken0IsClanker ,
tickUpper : -120000 ,
positionBps : 10_000 ,
},
],
},
fees : FEE_CONFIGS .StaticBasic ,
sniperFees : {
startingFee : 666_777 ,
endingFee : 41_673 ,
secondsToDecay : 15 ,
},
});
Chain-Specific WETH Addresses import { WETH_ADDRESSES } from 'clanker-sdk/constants' ;
const wethBase = WETH_ADDRESSES [8453 ];
const wethMainnet = WETH_ADDRESSES [1 ];
const wethArbitrum = WETH_ADDRESSES [42161 ];
LP Position Limits From the Solidity contracts:
Maximum LP Positions : 7
Position BPS Must Total : 10,000 (100%)
Tick Bounds : Must be within MIN_TICK and MAX_TICK
Tick Spacing : Ticks must be multiples of the pool's tick spacing
Lower Tick Constraint : tickLower must be >= tickIfToken0IsClanker
pool : {
positions : [
{ tickLower : -60000 , tickUpper : -30000 , positionBps : 5000 },
{ tickLower : -30000 , tickUpper : 0 , positionBps : 3000 },
{ tickLower : 0 , tickUpper : 30000 , positionBps : 2000 },
],
}
Best Practices
Start with defaults - Use standard positions unless you have specific needs
Reasonable market cap - Don't set unrealistically high initial valuations
Enable sniper protection - Protect early liquidity from bots
Consider pair token - WETH for most tokens, USDC for stables
Test configurations - Verify on testnet before mainnet
Respect contract limits - Max 7 LP positions, max 80% sniper fee, max 2 min decay
📖 Reference: rewards.md
Rewards Configuration Configure trading fee distribution for your Clanker token.
Overview Clanker tokens generate trading fees from the Uniswap V4 pool. You can configure how these fees are distributed among different recipients.
Basic Rewards Configuration rewards : {
recipients : [
{
recipient : account.address ,
admin : account.address ,
bps : 5000 ,
token : 'Both' ,
},
{
recipient : '0x...other...' ,
admin : '0x...other...' ,
bps : 5000 ,
token : 'Both' ,
},
],
}
Basis Points (bps) Fees are specified in basis points where:
100 bps = 1%
1000 bps = 10%
5000 bps = 50%
10000 bps = 100%
Total rewards must equal 10000 bps (100%).
Contract Limits From the Solidity contracts:
Maximum Reward Recipients : 7
Total BPS Must Equal : 10,000 (100%)
No Zero Addresses : All admin and recipient addresses must be non-zero
No Zero Amounts : Each recipient must have bps > 0
Token Types Choose which tokens each recipient receives from trading fees:
Token Type Description 'Clanker'Receive only the deployed token 'Paired'Receive only the paired token (e.g., WETH) 'Both'Receive both tokens
recipients : [
{
recipient : account.address ,
admin : account.address ,
bps : 10000 ,
token : 'Paired' ,
},
]
Recommendation : Use 'Paired' for simpler fee management since WETH is more liquid and easier to convert.
Single Recipient Receive all fees to one address:
rewards : {
recipients : [
{
recipient : account.address ,
admin : account.address ,
bps : 10000 ,
token : 'Both' ,
},
],
}
Multiple Recipients Split fees between creator and interface:
rewards : {
recipients : [
{
recipient : '0x...creator...' ,
admin : '0x...creator...' ,
bps : 7500 ,
token : 'Both' ,
},
{
recipient : '0x...interface...' ,
admin : '0x...interface...' ,
bps : 2500 ,
token : 'Both' ,
},
],
}
Default Bankr Interface Fee When deploying via Bankr, use this standard configuration with 20% interface fee:
const BANKR_INTERFACE_ADDRESS = '0xF60633D02690e2A15A54AB919925F3d038Df163e' ;
rewards : {
recipients : [
{
recipient : account.address ,
admin : account.address ,
bps : 8000 ,
token : 'Paired' ,
},
{
recipient : BANKR_INTERFACE_ADDRESS ,
admin : BANKR_INTERFACE_ADDRESS ,
bps : 2000 ,
token : 'Paired' ,
},
],
}
This is the default and recommended configuration for all token deployments via Bankr. Both recipients receive fees in the paired token (e.g., WETH) to simplify fee management.
Check Available Rewards Query unclaimed rewards for a recipient:
const TOKEN_ADDRESS = '0x...' ;
const FEE_OWNER_ADDRESS = '0x...' ;
const availableFees = await clanker.availableRewards ({
token : TOKEN_ADDRESS ,
rewardRecipient : FEE_OWNER_ADDRESS ,
});
console .log ('Available fees:' , availableFees);
Claim Rewards Claim accumulated trading fees:
const TOKEN_ADDRESS = '0x...' ;
const FEE_OWNER_ADDRESS = '0x...' ;
const { txHash, error } = await clanker.claimRewards ({
token : TOKEN_ADDRESS ,
rewardRecipient : FEE_OWNER_ADDRESS ,
});
if (error) {
console .error ('Claim failed:' , error.message );
} else {
console .log ('Rewards claimed:' , txHash);
}
Update Reward Recipient Change where rewards are sent (must be called by admin):
const { txHash, error } = await clanker.updateRewardRecipient ({
token : TOKEN_ADDRESS ,
oldRecipient : '0x...old...' ,
newRecipient : '0x...new...' ,
});
Update Reward Admin Transfer admin rights to a new address:
const { txHash, error } = await clanker.updateRewardAdmin ({
token : TOKEN_ADDRESS ,
recipient : '0x...recipient...' ,
newAdmin : '0x...newAdmin...' ,
});
Read-Only Rewards Check Check rewards without needing a wallet:
import { createPublicClient, http, type PublicClient } from 'viem' ;
import { base } from 'viem/chains' ;
import { Clanker } from 'clanker-sdk/v4' ;
const publicClient = createPublicClient ({
chain : base,
transport : http (),
}) as PublicClient ;
const clanker = new Clanker ({ publicClient });
const availableFees = await clanker.availableRewards ({
token : TOKEN_ADDRESS ,
rewardRecipient : FEE_OWNER_ADDRESS ,
});
Complete Rewards Example import { createPublicClient, createWalletClient, http, type PublicClient } from 'viem' ;
import { privateKeyToAccount } from 'viem/accounts' ;
import { base } from 'viem/chains' ;
import { Clanker } from 'clanker-sdk/v4' ;
const PRIVATE_KEY = process.env .PRIVATE_KEY as `0x${string } ` ;
const account = privateKeyToAccount (PRIVATE_KEY );
const publicClient = createPublicClient ({ chain : base, transport : http () }) as PublicClient ;
const wallet = createWalletClient ({ account, chain : base, transport : http () });
const clanker = new Clanker ({ wallet, publicClient });
const TOKEN_ADDRESS = '0x1A84F1eD13C733e689AACffFb12e0999907357F0' ;
const FEE_OWNER_ADDRESS = '0x46e2c233a4C5CcBD6f48073F8808E0e4b3296477' ;
const availableFees = await clanker.availableRewards ({
token : TOKEN_ADDRESS ,
rewardRecipient : FEE_OWNER_ADDRESS ,
});
console .log ('Available fees:' , availableFees);
if (availableFees.token0 > 0n || availableFees.token1 > 0n ) {
const { txHash, error } = await clanker.claimRewards ({
token : TOKEN_ADDRESS ,
rewardRecipient : FEE_OWNER_ADDRESS ,
});
if (error) {
console .error ('Claim failed:' , error.message );
} else {
console .log ('Transaction hash:' , txHash);
}
}
Best Practices
Secure admin addresses - Use multisig for high-value tokens
Document fee split - Be transparent with community about distribution
Regular claims - Don't let rewards accumulate excessively
Test updates - Verify recipient/admin changes on testnet first
Fair distribution - Consider community expectations for fee splits
📖 Reference: troubleshooting.md
Troubleshooting Common issues and solutions when using the Clanker SDK.
Setup Issues
"Missing PRIVATE_KEY env var" Cause: Environment variable not set or not in correct format.
export PRIVATE_KEY=0x...your_64_character_hex_key...
PRIVATE_KEY=0x...your_64_character_hex_key...
"Invalid private key format" Cause: Private key missing 0x prefix or incorrect length.
const PRIVATE_KEY = process.env .PRIVATE_KEY ;
if (!PRIVATE_KEY || !isHex (PRIVATE_KEY )) {
throw new Error ('PRIVATE_KEY must be a hex string starting with 0x' );
}
TypeScript Import Errors Cause: Incorrect import paths or missing viem peer dependency.
npm install clanker-sdk viem
import { Clanker } from 'clanker-sdk' ;
import { Clanker } from 'clanker-sdk/v4' ;
import { createAirdrop } from 'clanker-sdk/v4/extensions' ;
Deployment Issues
"Insufficient balance" Cause: Wallet doesn't have enough native token for gas.
const balance = await publicClient.getBalance ({ address : account.address });
console .log ('Balance:' , formatEther (balance), 'ETH' );
"Transaction reverted" Cause: Invalid configuration or contract state issue.
try {
await clanker.deploySimulate (config);
console .log ('Simulation passed' );
} catch (error) {
console .error ('Would revert:' , error);
}
Check configuration values:
if (!config.name || !config.symbol ) {
throw new Error ('Name and symbol required' );
}
if (config.vault ?.percentage > 30 ) {
throw new Error ('Vault percentage max is 30%' );
}
const totalBps = config.rewards ?.recipients ?.reduce (
(sum, r ) => sum + r.bps , 0
) || 0 ;
if (totalBps !== 10000 ) {
throw new Error ('Rewards must total 10000 bps' );
}
"Invalid image" Cause: IPFS hash not accessible or invalid format.
const image = 'ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi' ;
"Transaction pending too long" Cause: Gas price too low or network congestion.
const { address, error } = await Promise .race ([
waitForTransaction (),
new Promise ((_, reject ) =>
setTimeout (() => reject (new Error ('Timeout' )), 120000 )
),
]);
const receipt = await publicClient.getTransactionReceipt ({ hash : txHash });
Chain-Specific Issues
Monad: "Dynamic fees not supported" Cause: Monad only supports static fee configurations.
import { FEE_CONFIGS } from 'clanker-sdk/constants' ;
fees : FEE_CONFIGS .StaticBasic ,
Wrong Chain Cause: Wallet and publicClient configured for different chains.
const CHAIN = base;
const publicClient = createPublicClient ({
chain : CHAIN ,
transport : http (),
});
const wallet = createWalletClient ({
account,
chain : CHAIN ,
transport : http (),
});
const { txHash } = await clanker.deploy ({
chainId : CHAIN .id ,
});
Post-Deployment Issues
"No vault tokens to claim" Cause: Lockup period hasn't passed yet.
const claimable = await clanker.getVaultClaimableAmount ({ token : TOKEN_ADDRESS });
console .log ('Claimable:' , claimable.toString ());
"Cannot claim rewards" Cause: Not the reward recipient or no rewards accumulated.
const available = await clanker.availableRewards ({
token : TOKEN_ADDRESS ,
rewardRecipient : YOUR_ADDRESS ,
});
console .log ('Available:' , available);
"Cannot update metadata" Cause: Not the token admin.
console .log ('Your address:' , account.address );
Airdrop Issues
"Airdrop not registered" Cause: Didn't wait for indexing before registering.
await sleep (10_000 );
await registerAirdrop (tokenAddress, tree);
"Invalid proof" Cause: Merkle tree mismatch or wrong address.
const { tree, airdrop } = createAirdrop (originalRecipients);
const proof = getAllowlistMerkleProof (tree, entries, address.toLowerCase (), amount);
RPC Issues
"Rate limited" Cause: Public RPC rate limits exceeded.
const publicClient = createPublicClient ({
chain : base,
transport : http (process.env .RPC_URL_BASE ),
});
"Request failed" Cause: Network issues or RPC unavailable.
async function deployWithRetry (config, maxRetries = 3 ) {
for (let i = 0 ; i < maxRetries; i++) {
try {
return await clanker.deploy (config);
} catch (error) {
if (i === maxRetries - 1 ) throw error;
await sleep (1000 * (i + 1 ));
}
}
}
Contract Error Reference Common revert reasons from the Solidity contracts:
Error Cause Solution VaultLockupDurationTooShortLockup < 7 days Set lockupDuration ≥ 604800 AirdropLockupDurationTooShortLockup < 1 day Set lockupDuration ≥ 86400 MaxExtensionBpsExceededExtensions > 90% Reduce total extension percentage MaxExtensionsExceededMore than 10 extensions Use fewer extensions TooManyRewardParticipantsMore than 7 recipients Reduce reward recipients TooManyPositionsMore than 7 LP positions Use fewer positions InvalidRewardBpsRewards ≠ 10000 bps Ensure rewards total exactly 10000 StartingFeeGreaterThanMaxLpFeeSniper fee > 80% Set startingFee ≤ 800000 TimeDecayLongerThanMaxMevDelayDecay > 2 min Set secondsToDecay ≤ 120 StartingFeeMustBeGreaterThanEndingFeestartingFee ≤ endingFee Increase starting or decrease ending fee
Debug Checklist
✅ Private key set and valid (starts with 0x)
✅ Wallet funded with native token
✅ Chain configuration consistent
✅ IPFS image accessible
✅ Required fields provided (name, symbol, image, tokenAdmin)
✅ Total extension BPS ≤ 9000 (90%)
✅ Vault lockup ≥ 7 days (604800 seconds)
✅ Airdrop lockup ≥ 1 day (86400 seconds)
✅ Rewards total = 10000 bps exactly
✅ Reward recipients ≤ 7
✅ LP positions ≤ 7
✅ Sniper startingFee ≤ 800000 (80%)
✅ Sniper secondsToDecay ≤ 120 (2 minutes)
✅ Static fees for Monad chain
✅ Waited for indexing before airdrop registration
✅ Using correct recipient address for claims
Getting Help
📖 Reference: vesting.md
Token Vesting (Vault) Configure token vesting with lockup periods and linear vesting using the Clanker vault system.
Overview The vault system allows you to lock a percentage of the token supply with:
Lockup Duration : Cliff period before any tokens can be claimed
Vesting Duration : Linear vesting period after lockup
Recipient : Address that receives vested tokens
Basic Vault Configuration const { txHash, waitForTransaction, error } = await clanker.deploy ({
name : 'My Token' ,
symbol : 'TKN' ,
image : 'ipfs://...' ,
tokenAdmin : account.address ,
vault : {
percentage : 10 ,
lockupDuration : 2592000 ,
vestingDuration : 2592000 ,
recipient : account.address ,
},
});
Duration Values Common duration values in seconds:
Duration Seconds 1 hour 3600 1 day 86400 7 days 604800 14 days 1209600 30 days 2592000 60 days 5184000 90 days 7776000 180 days 15552000 1 year 31536000
Contract Limits From the Solidity contracts:
Minimum Lockup Duration : 7 days (enforced on-chain)
Maximum Extension BPS : 9000 (90% of supply can go to extensions total)
Minimum to LP : 10% of supply must go to liquidity pool
vault : {
percentage : 10 ,
lockupDuration : 604800 ,
vestingDuration : 2592000 ,
}
Note : The vault is one of several possible extensions. The total of all extension percentages (vault + airdrop + etc.) cannot exceed 90%.
Check Claimable Amount After deployment, check how many tokens are available to claim:
const TOKEN_ADDRESS = '0x...' ;
const claimable = await clanker.getVaultClaimableAmount ({
token : TOKEN_ADDRESS ,
});
console .log ('Claimable amount:' , claimable.toString ());
Claim Vaulted Tokens Claim tokens once the lockup period has passed:
const TOKEN_ADDRESS = '0x...' ;
const claimable = await clanker.getVaultClaimableAmount ({
token : TOKEN_ADDRESS ,
});
if (claimable > 0n ) {
const { txHash, error } = await clanker.claimVaultedTokens ({
token : TOKEN_ADDRESS ,
});
if (error) {
console .error ('Claim failed:' , error.message );
} else {
console .log ('Claim transaction:' , txHash);
}
} else {
console .log ('No tokens available to claim yet' );
}
Get Vault Claim Transaction Get the transaction object for claiming (useful for batching or custom signing):
const txObject = await clanker.getVaultClaimTransaction ({
token : TOKEN_ADDRESS ,
});
console .log ('Transaction object:' , txObject);
Vesting Timeline Example For a 10% vault with 30-day lockup and 30-day vesting:
Day 0: Token deployed, 10% locked in vault
↓
Day 1-30: Lockup period (nothing claimable)
↓
Day 31: Vesting begins
~3.33% claimable (1/30 of vaulted amount)
↓
Day 45: ~50% of vaulted tokens claimable
↓
Day 60: 100% claimable
Custom Recipient Set a different address to receive vested tokens:
vault : {
percentage : 10 ,
lockupDuration : 2592000 ,
vestingDuration : 2592000 ,
recipient : '0x...treasury_address...' ,
}
If not specified, recipient defaults to tokenAdmin.
Team Vesting Example Configure vesting for a team allocation:
const THIRTY_DAYS = 2592000 ;
const SIX_MONTHS = 15552000 ;
const { txHash, waitForTransaction, error } = await clanker.deploy ({
name : 'Team Token' ,
symbol : 'TEAM' ,
image : 'ipfs://...' ,
tokenAdmin : account.address ,
vault : {
percentage : 20 ,
lockupDuration : SIX_MONTHS ,
vestingDuration : SIX_MONTHS * 2 ,
recipient : '0x...team_multisig...' ,
},
metadata : {
description : 'Token with team vesting schedule' ,
},
context : {
interface : 'Clanker SDK' ,
},
});
No Vesting To deploy without any vesting, simply omit the vault configuration:
const { txHash, waitForTransaction, error } = await clanker.deploy ({
name : 'My Token' ,
symbol : 'TKN' ,
image : 'ipfs://...' ,
tokenAdmin : account.address ,
});
Best Practices
Reasonable lockup periods - Align with project milestones
Gradual vesting - Avoid cliff-only (0 vesting duration)
Transparent communication - Share vesting schedule with community
Secure recipient - Use multisig for team vesting
Test first - Verify vesting math before mainnet