Skip to main content

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 in packages/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​

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​

FormatPatternExampleUsed For
tokenNameLetters and digits, 1-25 chars'anime'Bonding curve ops, price
token id / class keycollection|category|type|additionalKey'GALA|Unit|none|none'Transfers, balances, locks, standard tokens

Common Mistakes Table​

❌ Wrong✅ CorrectWhy
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 tokensCheck isGraduated, trade on the DEX with gswap-sdk if trueGraduated 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​

MethodtokenNametoken idNotes
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

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 showcase
  • npm run demo:read-only - Wallet-free operations
  • npm 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 operations
  • npm run demo:bonding:graduation - Token graduation workflow and simulation
  • npm run demo:bonding:pool-discovery - Pool filtering and discovery
  • npm run demo:bonding:price-impact - Price impact analysis and calculations
  • npm run demo:bonding:token-launch - Token launch lifecycle demonstration
  • npm run demo:bonding:volume-trading - High-volume trading simulation
  • npm run demo:bonding:pool-analysis - Deep pool analytics and metrics
  • npm run demo:bonding:user-holder - Holder context
  • npm run demo:bonding:pagination-variants - Pagination variants
  • npm 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 launches
  • npm run demo:watch:integration - Token creation integration
  • npm run demo:monitoring:stream-events - Stream events
  • npm 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 management
  • npm run demo:streaming:recordings - Recording management
  • npm run demo:streaming:simulcast - Simulcast target management
  • npm run demo:chat - REST chat operations
  • npm run demo:chat:websocket - WebSocket real-time chat
  • npm 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 performance
  • npm run demo:token-supply - Token supply metrics from GalaChain
  • npm run demo:utilities:balance - Single token balance check
  • npm run demo:utilities:multi-token-portfolio - Multi-token portfolio
  • npm 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.