Token Factories
Token Metadata
All token launches require metadata:
type TokenMetadata = {
name: string; // Token name (e.g., "My Token")
symbol: string; // Token symbol (e.g., "MTK")
decimals?: number; // Number of decimals (default: 9)
uri?: string; // Optional URI to JSON metadata
};Creating Token Metadata Helper
The SDK provides a createTokenMetadata() helper function that validates and formats your token metadata:
import { createTokenMetadata } from "@vertigo-amm/vertigo-sdk";
// Create and validate token metadata
const metadata = createTokenMetadata(
"My Amazing Token", // name (max 32 characters)
"MAT", // symbol (max 10 characters)
"https://example.com/token-metadata.json" // URI to off-chain metadata
);The helper automatically:
✅ Validates name length (1-32 characters)
✅ Validates symbol length (1-10 characters)
✅ Trims whitespace from all fields
✅ Uppercases the symbol
✅ Ensures URI is provided
✅ Throws clear error messages if validation fails
Example with factory:
import { Vertigo, createTokenMetadata } from "@vertigo-amm/vertigo-sdk";
const vertigo = await Vertigo.load({ connection, wallet });
// Create validated metadata
const metadata = createTokenMetadata(
"My Launch Token",
"MLT",
"https://example.com/metadata.json"
);
// Use with token factory
const result = await vertigo.factory.launchTokenWithPool({
metadata,
supply: 1_000_000_000,
initialMarketCap: 50 * LAMPORTS_PER_SOL,
royaltiesBps: 250,
});Example: Launch a simple token
Create a token without a pool:
import { Vertigo } from "@vertigo-amm/vertigo-sdk";
import { Connection } from "@solana/web3.js";
import * as anchor from "@coral-xyz/anchor";
async function main() {
const connection = new Connection("https://api.devnet.solana.com", "confirmed");
const walletKeypair = anchor.Wallet.local();
const vertigo = await Vertigo.load({
connection,
wallet: walletKeypair,
network: "devnet",
});
// Launch a standard SPL token
const { signature, mintAddress } = await vertigo.factory.launchToken({
metadata: {
name: "My Token",
symbol: "MTK",
decimals: 9,
uri: "https://example.com/token-metadata.json", // Optional
},
supply: 1_000_000, // 1 million tokens (will be multiplied by 10^decimals)
useToken2022: false, // Use SPL token (default)
});
console.log(`Token created: ${mintAddress.toBase58()}`);
console.log(`Transaction: ${signature}`);
}
main();Example: Launch a Token-2022 token
The same API works for Token-2022:
import { Vertigo } from "@vertigo-amm/vertigo-sdk";
import { Connection } from "@solana/web3.js";
import * as anchor from "@coral-xyz/anchor";
async function main() {
const connection = new Connection("https://api.devnet.solana.com", "confirmed");
const walletKeypair = anchor.Wallet.local();
const vertigo = await Vertigo.load({
connection,
wallet: walletKeypair,
network: "devnet",
});
// Launch a Token-2022 token
const { signature, mintAddress } = await vertigo.factory.launchToken({
metadata: {
name: "My Token 2022",
symbol: "MT22",
decimals: 6,
},
supply: 10_000_000, // 10 million tokens
useToken2022: true, // Use Token-2022 program
});
console.log(`Token-2022 created: ${mintAddress.toBase58()}`);
console.log(`Transaction: ${signature}`);
}
main();Example: Launch token with liquidity pool
Create a token and pool in one operation:
import { Vertigo } from "@vertigo-amm/vertigo-sdk";
import { Connection, LAMPORTS_PER_SOL } from "@solana/web3.js";
import * as anchor from "@coral-xyz/anchor";
async function main() {
const connection = new Connection("https://api.devnet.solana.com", "confirmed");
const walletKeypair = anchor.Wallet.local();
const vertigo = await Vertigo.load({
connection,
wallet: walletKeypair,
network: "devnet",
});
// Launch token with liquidity pool
const result = await vertigo.factory.launchTokenWithPool({
metadata: {
name: "My Launch Token",
symbol: "MLT",
decimals: 9,
uri: "https://example.com/metadata.json",
},
supply: 1_000_000_000, // 1 billion tokens
initialMarketCap: 50 * LAMPORTS_PER_SOL, // 50 SOL market cap
royaltiesBps: 250, // 2.5% trading fees
useToken2022: false,
});
console.log(`Token created: ${result.mintAddress.toBase58()}`);
console.log(`Pool created: ${result.poolAddress.toBase58()}`);
console.log(`Token transaction: ${result.tokenSignature}`);
console.log(`Pool transaction: ${result.poolSignature}`);
}
main();Example: Launch with custom timing
Schedule a launch for a specific time:
import { Vertigo } from "@vertigo-amm/vertigo-sdk";
import { Connection, LAMPORTS_PER_SOL } from "@solana/web3.js";
import * as anchor from "@coral-xyz/anchor";
async function main() {
const connection = new Connection("https://api.devnet.solana.com", "confirmed");
const walletKeypair = anchor.Wallet.local();
const vertigo = await Vertigo.load({
connection,
wallet: walletKeypair,
network: "devnet",
});
// Launch 24 hours from now
const launchTime = new anchor.BN(Math.floor(Date.now() / 1000) + 86400);
const result = await vertigo.factory.launchTokenWithPool({
metadata: {
name: "Scheduled Launch Token",
symbol: "SLT",
decimals: 9,
},
supply: 1_000_000_000,
initialMarketCap: 100 * LAMPORTS_PER_SOL,
royaltiesBps: 100, // 1% fees
launchTime, // Unix timestamp
});
console.log(`Token will launch at: ${new Date(launchTime.toNumber() * 1000)}`);
console.log(`Pool address: ${result.poolAddress.toBase58()}`);
}
main();Parameters Reference
LaunchTokenParams
metadata - Token metadata object
name - Token display name
symbol - Token symbol/ticker
decimals - Number of decimals (default: 9)
uri - Optional metadata URI
supply - Total token supply in whole units
useToken2022 - Use Token-2022 instead of SPL (default: false)
LaunchTokenWithPoolParams
All of LaunchTokenParams, plus:
initialMarketCap - Starting market cap in lamports
royaltiesBps - Trading fee in basis points (e.g., 250 = 2.5%)
launchTime - Optional Unix timestamp for scheduled launch
Migration from v1
v1 (Old) - SPL Token Factory
// Initialize factory
await vertigo.SPLTokenFactory.initialize({
payer,
owner,
mintA: NATIVE_MINT,
params: {
shift: new anchor.BN(100 * LAMPORTS_PER_SOL),
initialTokenReserves: new anchor.BN(1_000_000_000),
feeParams: { /* ... */ },
tokenParams: { /* ... */ },
nonce: 0,
},
});
// Launch from factory
await vertigo.SPLTokenFactory.launch({
payer,
owner,
mintA: NATIVE_MINT,
mintB,
mintBAuthority,
tokenProgramA: TOKEN_PROGRAM_ID,
params: { /* ... */ },
});v2 (New) - Unified Factory
// No initialization needed - just launch!
const result = await vertigo.factory.launchTokenWithPool({
metadata: {
name: "My Token",
symbol: "MTK",
decimals: 9,
},
supply: 1_000_000_000,
initialMarketCap: 50 * LAMPORTS_PER_SOL,
royaltiesBps: 250,
});Key Improvements in v2
No initialization required - Just launch directly
Simplified parameters - No need to specify token programs, authorities, etc.
Unified interface - Same API for SPL and Token-2022
Automatic handling - Token accounts, minting, etc. handled automatically
Better error messages - Clear, actionable error messages
Type safety - Full TypeScript support with IntelliSense
Advanced: Pool Authority Client
For advanced pool management and custom configurations, use the Pool Authority Client:
import { PoolAuthority } from "@vertigo-amm/vertigo-sdk";
const poolAuth = await PoolAuthority.load({
connection,
wallet,
});
// Create pools with custom authority settings
// Note: This is for advanced use casesThe Pool Authority Client is for advanced users who need fine-grained control over pool creation. Most users should use the standard Factory Client's launchTokenWithPool() method.
Custom Token Factories
While Vertigo provides default factories, you can build custom factories for your specific launchpad needs:
Use the Factory Client as a starting point
Extend functionality with custom validation
Add custom metadata or launch mechanics
Integrate with your own smart contracts
For guidance on building custom factories, see Designing Token Factories.
Error Handling
try {
const result = await vertigo.factory.launchTokenWithPool({
metadata: { name: "My Token", symbol: "MTK" },
supply: 1_000_000,
initialMarketCap: 50 * LAMPORTS_PER_SOL,
royaltiesBps: 250,
});
console.log(`Success: ${result.poolAddress.toBase58()}`);
} catch (error) {
if (error.message.includes("Wallet not connected")) {
console.error("Please connect a wallet first");
} else if (error.message.includes("Insufficient funds")) {
console.error("Not enough SOL to create token and pool");
} else {
console.error(`Launch failed: ${error.message}`);
}
}Tips
The initial supply is minted to your wallet's associated token account
Market cap is the initial virtual SOL backing the pool
Royalties are trading fees that accrue to the pool owner
Always test on devnet before launching on mainnet
Consider using
launchTimefor coordinated launchesToken-2022 offers advanced features but requires compatible wallets
Use the
createTokenMetadata()helper to ensure metadata is properly validated
Last updated

