Gala Launchpad SDK - Usage Examples
Practical code examples for the launchpad SDK (9.0.0), organized by category. For complete API documentation, see API Reference.
9.0 is launchpad-only. The DEX (quotes, swaps, pools, liquidity, fees, market prices, leaderboards) is
@gala-chain/gswap-sdk; its runnable demos are inpackages/gswap-sdk/examples/demos. Gateway-generic pieces (signers, wallet providers, React hooks, the bridge) are@gala-chain/gala-core-sdk's. See MIGRATING-TO-9.0.md for where each removed export went.
Table of Contents
- Token Format Decision Tree
- Quick Start
- Recommended Learning Path
- Core Operations
- Bonding Curve Trading
- Real-Time Monitoring
- Streaming & Chat
- Utilities
- Error Handling
Token Format Decision Tree
Launchpad tokens are addressed by tokenName; standard GalaChain tokens by a token id (collection|category|type|additionalKey).
Q: What operation am I performing?
│
├── Buying/selling tokens on the bonding curve (pre-graduation)?
│ └── Use tokenName: sdk.buy({ tokenName: 'anime', amount: '100', type: 'native' })
│
├── Transferring tokens?
│ ├── Launchpad token? → sdk.transferToken({ tokenName: 'anime', ... })
│ └── Standard GalaChain token? → sdk.transferToken({ tokenId: 'GALA|Unit|none|none', ... })
│
├── Checking a launchpad token's price?
│ └── sdk.fetchTokenPrice({ tokenName: 'anime' }) (bonding curve, or the swap backend once graduated)
│
├── Need a launchpad token's class key?
│ └── await sdk.resolveTokenClassKey('anime') (never construct it by hand)
│
├── Trading a graduated token / any other token on the DEX, or a price by token id?
│ └── @gala-chain/gswap-sdk: gSwap.swaps.swap(...), gSwap.market.getPrice(tokenId)
│
└── Graduating a token from bonding curve to DEX?
└── Use tokenName: sdk.graduateToken('anime')
Format Reference
| Format | Pattern | Example | Used For |
|---|---|---|---|
| tokenName | Letters and digits, 1-25 chars | 'anime' | Bonding curve ops, price |
| token id / class key | collection|category|type|additionalKey | 'GALA|Unit|none|none' | Transfers, balances, locks, standard tokens |
Common Mistakes Table
| ❌ Wrong | ✅ Correct | Why |
|---|---|---|
sdk.buy({ tokenName: 'ANIME|Unit|...' }) | sdk.buy({ tokenName: 'anime' }) | Bonding curve uses simple names |
sdk.fetchTokenPrice({ tokenId: 'GALA|Unit|none|none' }) | gSwap.market.getPrice('GALA|Unit|none|none') (gswap-sdk) | 9.0 prices launchpad tokens only; a tokenId is refused with a ValidationError |
Assuming buy() works for graduated tokens | Check isGraduated, trade on the DEX with gswap-sdk if true | Graduated tokens trade on the DEX |
Detecting Graduation Status
const pool = await sdk.fetchPools({ tokenName: 'anime' });
const isGraduated = pool.items[0]?.isGraduated ?? false;
if (isGraduated) {
// Token is on the DEX: trade it with @gala-chain/gswap-sdk using its class key.
// Always resolve the key, never construct it: the symbol may differ from the tokenName.
const tokenClassKey = await sdk.resolveTokenClassKey('anime');
console.log('Trade on the DEX with', tokenClassKey);
} else {
console.log('Still on the bonding curve: use sdk.buy / sdk.sell with tokenName "anime"');
}
Method Reference
| Method | tokenName | token id | Notes |
|---|---|---|---|
buy() | ✅ | ❌ | Bonding curve only |
sell() | ✅ | ❌ | Bonding curve only |
graduateToken() | ✅ | ❌ | Triggers DEX migration |
calculateBuyAmount() | ✅ | ❌ | Pre-trade calculation |
calculateSellAmount() | ✅ | ❌ | Pre-trade calculation |
fetchPools() | ✅ | ❌ | Query bonding curve pools |
fetchTokenPrice() | ✅ | ❌ | Launchpad token price ({ tokenName } only) |
transferToken() | ✅ | ✅ | Both work |
lockTokens() | ✅ | ✅ | Both work |
fetchTokenBalance() | ✅ | ✅ | Both work |
See Also: For complete type definitions and utilities, see
src/types/token.types.ts
Quick Start
Installation
npm install @gala-chain/launchpad-sdk@next @gala-chain/gala-core-sdk@next zod
@gala-chain/gala-core-sdk and zod are peer dependencies. 9.0 is a release candidate under the
next dist-tag (an install without @next gets 8.1.0).
Basic Setup
import { createLaunchpadSDK } from '@gala-chain/launchpad-sdk';
// Read-only mode (no wallet required)
const sdk = createLaunchpadSDK({ env: 'prod' });
// Full-access mode (with wallet for trading)
const sdkWithWallet = createLaunchpadSDK({
env: 'prod',
privateKey: process.env.WALLET_PRIVATE_KEY
});
Run Your First Demo
# Complete SDK feature demonstration
npm run demo
# Basic bonding curve buy/sell
npm run demo:trades
# Watch for new launchpad token launches
npm run demo:watch:tokens
Recommended Learning Path
1. Start with Core Operations
npm run demo # Complete SDK overview
npm run demo:read-only # Read-only operations (no wallet needed)
npm run demo:authenticated # Authenticated operations (wallet required)
Learn: SDK initialization, configuration, read-only vs full-access modes
2. Understand Bonding Curve Trading
npm run demo:trades # Basic buy/sell operations
npm run demo:bonding:graduation # Token graduation workflow
npm run demo:bonding:pool-discovery # Pool filtering and discovery
Learn: Pre-graduation token trading, bonding curve mechanics, token launch lifecycle
3. Try Real-Time Features
npm run demo:watch:tokens # Watch for new launchpad token launches
npm run demo:monitoring:websocket-events
Learn: WebSocket event monitoring, token discovery
4. Explore Advanced Topics
npm run demo:cache # Metadata cache performance
npm run demo:token-supply # Token supply metrics from GalaChain
Learn: Performance optimization, token supply queries
5. The DEX
Swaps, liquidity, fees, pools and market data are @gala-chain/gswap-sdk's. Its demos:
packages/gswap-sdk/examples/demos/README.md
(npx tsx src/<dir>/<file>.ts).
Core Operations
Initialize SDK
Read-Only Mode (no wallet required):
import { createLaunchpadSDK } from '@gala-chain/launchpad-sdk';
const sdk = createLaunchpadSDK({
env: 'prod'
});
// Query operations work without wallet
const pools = await sdk.fetchPools({ type: 'popular', pageSize: 10 });
const price = await sdk.fetchTokenPrice({ tokenName: 'anime' });
Full-Access Mode (with wallet for trading):
const sdk = createLaunchpadSDK({
env: 'prod',
privateKey: process.env.WALLET_PRIVATE_KEY!
});
// Now you can submit trades
const result = await sdk.buy({ tokenName: 'anime', amount: '100', type: 'native', expectedAmount: '1' });
Dynamic Wallet Configuration:
import { Wallet } from 'ethers';
// Start in read-only mode
const sdk = createLaunchpadSDK({ env: 'prod' });
// Later, upgrade to full-access
sdk.setWallet(new Wallet(process.env.WALLET_PRIVATE_KEY!));
// Now signing operations work
const result = await sdk.buy({ tokenName: 'anime', amount: '100', type: 'native', expectedAmount: '1' });
Demos:
npm run demo- Complete SDK showcasenpm run demo:read-only- Wallet-free operationsnpm run demo:authenticated- Wallet-required operations
Bonding Curve Trading
Trade tokens that are still in bonding curve pools (pre-graduation).
Buy Tokens on Bonding Curve
const sdk = createLaunchpadSDK({
env: 'prod',
privateKey: process.env.WALLET_PRIVATE_KEY!
});
// Calculate purchase amounts
const quote = await sdk.calculateBuyAmount({
tokenName: 'anime',
amount: '100',
type: 'native'
});
console.log(`For 100 GALA:`);
console.log(` Receive: ${quote.amount} tokens`);
console.log(` Fees: ${quote.transactionFee} GALA transaction, ${quote.gasFee} GALA gas`);
// Execute purchase
const result = await sdk.buy({
tokenName: 'anime',
amount: '100',
type: 'native',
expectedAmount: quote.amount,
slippageToleranceFactor: 0.01
});
console.log(`✓ Purchase completed: ${result.transactionId}`);
Sell Tokens on Bonding Curve
// Calculate sale amounts
const quote = await sdk.calculateSellAmount({
tokenName: 'anime',
amount: '10000',
type: 'exact'
});
console.log(`Selling 10,000 tokens:`);
console.log(` Receive: ${quote.amount} GALA`);
console.log(` Fee: ${quote.reverseBondingCurveFee} GALA`);
// Execute sale
const result = await sdk.sell({
tokenName: 'anime',
amount: '10000',
type: 'exact',
expectedAmount: quote.amount,
slippageToleranceFactor: 0.01
});
console.log(`✓ Sale completed: ${result.transactionId}`);
Bonding Curve Demos:
npm run demo:trades- Basic buy/sell operationsnpm run demo:bonding:graduation- Token graduation workflow and simulationnpm run demo:bonding:pool-discovery- Pool filtering and discoverynpm run demo:bonding:price-impact- Price impact analysis and calculationsnpm run demo:bonding:token-launch- Token launch lifecycle demonstrationnpm run demo:bonding:volume-trading- High-volume trading simulationnpm run demo:bonding:pool-analysis- Deep pool analytics and metricsnpm run demo:bonding:user-holder- Holder contextnpm run demo:bonding:pagination-variants- Pagination variantsnpm run demo:bonding:pool-creator-filtering- Creator filtering
Real-Time Monitoring
Monitor token creation events with the SDK's watchers. (New DEX pools are gswap-sdk's:
gSwap.pools.watchNewPools().)
Watch for Launchpad Token Creation
// Monitor for new token launches
const unsubscribe = sdk.onLaunchpadTokenCreation(
(token) => {
console.log(`🚀 New token: ${token.tokenName}`);
console.log(` Symbol: ${token.symbol}`);
console.log(` Creator: ${token.creatorAddress}`);
console.log(` Created: ${new Date(token.createdAt).toISOString()}`);
},
{
creatorAddress: 'eth|...', // Optional: watch specific creator
intervalMs: 30000 // Poll every 30 seconds
}
);
// Stop watching after 2 minutes
setTimeout(() => {
unsubscribe();
console.log('Stopped watching for new tokens');
}, 120000);
Monitoring Demos:
npm run demo:watch:tokens- Watch for new launchpad token launchesnpm run demo:watch:integration- Token creation integrationnpm run demo:monitoring:stream-events- Stream eventsnpm run demo:monitoring:websocket-events- WebSocket event handlers
Streaming & Chat
Live streaming and real-time chat features for token communities.
Basic Stream Management
const sdk = createLaunchpadSDK({
env: 'prod',
privateKey: process.env.WALLET_PRIVATE_KEY!,
streamWebSocketUrl: 'wss://stream.example.com'
});
// Stream credentials (stream key, RTMP URL, playback id) of a token you own
const creds = await sdk.getStreamCredentials('mytoken');
console.log(`RTMPS URL: ${creds.rtmpsUrl}`);
console.log(`Playback ID: ${creds.playbackId}`);
// Check global streaming status
const globalStatus = await sdk.getGlobalStreamingStatus();
console.log(`Streaming enabled globally: ${globalStatus.enabled}`);
Engagement Statistics
// Engagement metrics for analytics dashboards arrive on the token room about every 15 seconds
// while there is chat activity
const unsubscribe = sdk.onEngagementStatsUpdated((event) => {
console.log(`${event.tokenName}: ${event.chat.messageCount} chat messages`);
console.log(`Comments: ${event.comments.count} from ${event.comments.uniqueCommenters} users`);
});
Real-Time Chat with WebSocket
// Connect to stream WebSocket with event handlers
await sdk.connectStreamWebSocket({
onTypingIndicator: (event) => {
const count = event.typingUsers.length;
if (count === 1) {
console.log(`${event.typingUsers[0]?.fullName} is typing...`);
} else if (count > 1) {
console.log(`${count} people are typing...`);
}
},
onChatMessage: (event) => {
console.log(`[${event.user?.fullName}]: ${event.content}`);
}
});
// Subscribe to a stream
await sdk.subscribeToStream('mytoken');
// Send typing indicators
sdk.sendTypingStart('mytoken');
// ... user types ...
sdk.sendTypingStop('mytoken');
// Send a message via WebSocket
await sdk.sendStreamChatViaWebSocket('mytoken', 'Hello everyone!');
// Cleanup
await sdk.unsubscribeFromStream('mytoken');
await sdk.disconnectStreamWebSocket();
Typing Indicators
// Typing indicators are ephemeral (not persisted)
// Auto-expire after 5 seconds of inactivity
// Start typing indicator
sdk.sendTypingStart('mytoken');
// Stop typing indicator (or wait for auto-expire)
sdk.sendTypingStop('mytoken');
// Handle typing events from other users
await sdk.connectStreamWebSocket({
onTypingIndicator: (event) => {
// event.typingUsers: TypingUser[]
// Each user has: userAddress, fullName, profileImage?
const names = event.typingUsers.map(u => u.fullName);
if (names.length === 0) {
console.log('No one is typing');
} else if (names.length === 1) {
console.log(`${names[0]} is typing...`);
} else if (names.length === 2) {
console.log(`${names[0]} and ${names[1]} are typing...`);
} else {
console.log('Several people are typing...');
}
}
});
Streaming & Chat Demos (a selection; npm run demo:list shows all):
npm run demo:streaming- Basic stream managementnpm run demo:streaming:recordings- Recording managementnpm run demo:streaming:simulcast- Simulcast target managementnpm run demo:chat- REST chat operationsnpm run demo:chat:websocket- WebSocket real-time chatnpm run demo:chat:typing-indicators- Typing indicator demo
Utilities
Portfolio & Balances
const sdk = createLaunchpadSDK({ env: 'prod' });
// GALA balance
const galaBalance = await sdk.fetchGalaBalance('eth|...');
console.log(`GALA: ${galaBalance?.quantity}`);
// Tokens you hold
const held = await sdk.fetchTokensHeld({
address: 'eth|...',
search: 'dragon' // Optional: filter by search
});
console.log('Tokens held:');
held.tokens.forEach(token => {
console.log(` ${token.symbol}: ${token.balance}`);
});
Token Supply Metrics
// Query GALA supply information
const supplies = await sdk.fetchTokenClassesWithSupply([
{
collection: 'GALA',
category: 'Unit',
type: 'none',
additionalKey: 'none'
}
]);
const gala = supplies[0];
if (gala === undefined) throw new Error('GALA token class not returned');
console.log(`Token: ${gala.symbol} (${gala.name})`);
console.log(`Total Supply: ${gala.totalSupply}`);
console.log(`Max Supply: ${gala.maxSupply}`);
console.log(`Total Burned: ${gala.totalBurned}`);
console.log(`Decimals: ${gala.decimals}`);
// Calculate health metrics
const totalSupply = parseFloat(gala.totalSupply);
const maxSupply = parseFloat(gala.maxSupply);
const burned = parseFloat(gala.totalBurned);
const circulationPercent = (totalSupply / maxSupply) * 100;
const burnPercent = (burned / totalSupply) * 100;
console.log(`\nCirculation: ${circulationPercent.toFixed(2)}% of max supply`);
console.log(`Burned: ${burnPercent.toFixed(2)}% of total supply`);
Metadata Cache Performance
// Warm cache by fetching pools
console.log('Warming cache...');
await sdk.fetchPools({ type: 'popular', pageSize: 50 });
// Check cache statistics
const stats = sdk.getCacheInfo();
console.log(`Cache warmed with ${stats.totalTokens} tokens`);
console.log(`Memory: ${(stats.cacheSize / 1024).toFixed(2)} KB`);
// Perform instant calculations using cached metadata
const tokens = ['anime', 'dragnrkti', 'rocketri'];
console.log('\nCalculating spot prices (instant, no network calls):');
console.time('Batch Calculations');
for (const token of tokens) {
const poolDetails = await sdk.fetchPoolDetailsForCalculation(token);
const buy100 = await sdk.calculateBuyAmountLocal({
tokenName: token,
amount: '100',
type: 'native',
currentSupply: poolDetails.currentSupply
});
console.log(`${token}: 100 GALA → ${buy100.amount} tokens`);
}
console.timeEnd('Batch Calculations');
// Output: Batch Calculations: ~50ms (vs ~2000ms without cache)
Utility Demos:
npm run demo:cache- Metadata cache warming and performancenpm run demo:token-supply- Token supply metrics from GalaChainnpm run demo:utilities:balance- Single token balance checknpm run demo:utilities:multi-token-portfolio- Multi-token portfolionpm run demo:utilities:trade-history- Trade history
Wallet balances and price history on the DEX are gswap-sdk's (src/assets/balances.ts,
src/market/price-history.ts in its demos).
Error Handling
Common error patterns and solutions.
Wallet Requirements
import { ValidationError } from '@gala-chain/launchpad-sdk';
const sdk = createLaunchpadSDK({ env: 'prod' });
// No wallet configured
try {
await sdk.buy({ tokenName: 'anime', amount: '100', type: 'native', expectedAmount: '1' });
} catch (error) {
if (error instanceof ValidationError && error.code === 'WALLET_REQUIRED') {
console.log('This operation requires a wallet');
console.log('Configure wallet: sdk.setWallet(privateKey)');
}
}
Slippage Protection
try {
const quote = await sdk.calculateBuyAmount({ tokenName: 'anime', amount: '1000', type: 'native' });
await sdk.buy({
tokenName: 'anime',
amount: '1000',
type: 'native',
expectedAmount: quote.amount,
slippageToleranceFactor: 0.01
});
} catch (error) {
if (error instanceof Error && error.message.includes('slippage')) {
console.log('Price moved beyond slippage tolerance');
console.log('Increase slippage or retry with a fresh quote');
}
}
More Examples
See the examples/ directory for the working demos by category (examples/README.md lists them);
npm run demo:list browses them. DEX demos live in
packages/gswap-sdk/examples/demos.
For migration from old demo structure, see docs/DEMO_MIGRATION_GUIDE.md in the package.