Package Exports
- @gala-chain/launchpad-sdk
Readme
Gala Launchpad SDK
A comprehensive TypeScript SDK for the Gala Launchpad Backend API, providing type-safe authentication, trading, and real-time features for DeFi applications.
Features
Clean Result Types with No Wrapper Overhead:
- Direct Result Access: Get clean, typed results without wrapper objects
- Semantic Type Conversion: Dates as Date objects, numbers as numbers, strings for precision
- Comprehensive Type Safety: Full TypeScript support with precise result interfaces
- Zero Wrapper Overhead: No more
result.data.success- direct property access - Options Object Pattern: All methods with 2+ parameters use clean options objects
- Auto-Pagination: Automatic multi-page fetching with configurable concurrency
Developer Experience
import { createLaunchpadSDK, createWallet } from '@gala-chain/launchpad-sdk';
// Auto-detect wallet format and create SDK
const sdk = createLaunchpadSDK({
wallet: 'your-private-key-or-mnemonic' // Auto-detects format!
});
// Direct result access - no wrapper objects!
const pools = await sdk.fetchPools({ type: 'recent' });
console.log(`Found ${pools.total} pools`); // Direct property access
console.log(`Page ${pools.page} of ${pools.totalPages}`); // Clean pagination
console.log(`Has next: ${pools.hasNext}`); // Boolean convenience properties
// Clean typed results everywhere
const balance = await sdk.fetchGalaBalance();
console.log(`Balance: ${balance.balance} GALA`); // Direct balance access
console.log(`Last updated: ${balance.lastUpdated.toISOString()}`); // Date objectClean API Architecture
Direct result access with no wrapper overhead:
// Get pools with direct property access
const pools = await sdk.fetchPools({ type: 'recent' });
console.log(pools.pools); // Direct access to pool array
console.log(pools.total); // Immediate pagination info
console.log(pools.hasNext); // Computed convenience propertiesKey Features
- Type-Safe API Client: Full TypeScript support with comprehensive type definitions
- Clean Result Types: Direct property access without wrapper objects
- Options Object Pattern: All multi-parameter methods use clean options objects
- Auto-Pagination: Automatic multi-page fetching for large result sets
- Signature Authentication: Ethereum wallet-based authentication with automatic signature generation
- Helper Functions: Auto-detecting wallet creation and SDK factory functions
- Pool Management: Create, fetch, and check token pools on the launchpad
- Token Trading: Buy and sell tokens with slippage protection via GalaChain
- Token Transfers: Transfer GALA and launchpad tokens between wallets with EIP-712 signatures
- User Operations: Portfolio management, token balances, and account management
- Comment System: Post and retrieve comments on token pools
- Price History: Fetch historical price data for DEX tokens with pagination (Node.js only, requires MySQL)
- Comprehensive Validation: Input validation and error handling for all operations
- Multi-Environment Support: Production, staging, and custom backend URLs
Installation
NPM
npm install @gala-chain/launchpad-sdkYarn
yarn add @gala-chain/launchpad-sdkPeer Dependencies
This SDK requires the following peer dependencies to be installed:
npm install ethers@^6.15.0 @gala-chain/api@^2.4.3 @gala-chain/connect@^2.4.3 socket.io-client@^4.8.1 axios@^1.12.2 bignumber.js@^9.1.2 zod@^3.25.76Or with yarn:
yarn add ethers@^6.15.0 @gala-chain/api@^2.4.3 @gala-chain/connect@^2.4.3 socket.io-client@^4.8.1 axios@^1.12.2 bignumber.js@^9.1.2 zod@^3.25.76All peer dependencies are required - this includes socket.io-client which is needed for transaction verification via WebSocket.
Module Formats
The SDK is distributed in three module formats to support both modern and legacy projects:
ESM (ES Modules) - Primary Format
For modern bundlers and Node.js 16+:
import { createLaunchpadSDK } from '@gala-chain/launchpad-sdk';
const sdk = createLaunchpadSDK({
wallet: 'your-private-key-or-mnemonic'
});When to use:
- ✅ React, Vue, Svelte, Angular applications
- ✅ Next.js, Nuxt, SvelteKit
- ✅ Vite, Webpack, esbuild bundlers
- ✅ Modern Node.js projects with
"type": "module"
CommonJS - Legacy Support
For CommonJS projects and older Node.js environments:
const { createLaunchpadSDK } = require('@gala-chain/launchpad-sdk');
const sdk = createLaunchpadSDK({
wallet: 'your-private-key-or-mnemonic'
});When to use:
- ✅ Legacy Node.js projects with CommonJS modules
- ✅ Older tooling that doesn't support ESM
- ✅ Express.js, Nest.js (CommonJS mode)
- ✅ Projects without build tools
UMD (Universal Module Definition) - Browser Legacy
For browser globals and legacy environments:
<script src="node_modules/@gala-chain/launchpad-sdk/dist/index.js"></script>
<script>
const sdk = window.GalaLaunchpadSDK.createLaunchpadSDK({
wallet: 'your-private-key-or-mnemonic'
});
</script>When to use:
- ✅ Direct browser
<script>tags - ✅ Older browser environments
- ✅ CDN delivery
Module Resolution
Node.js automatically selects the correct module format based on your project:
| Project Type | Method | Format Used | File |
|---|---|---|---|
| ESM Module | import |
ESM | dist/index.esm.js |
| CommonJS | require() |
CommonJS | dist/index.cjs.js |
| Legacy Tools | Direct Include | UMD | dist/index.js |
No configuration needed - Node.js and bundlers automatically select the optimal format via the package exports field!
AI Agent Integration
For Claude Desktop Users
Install the MCP server to enable Claude to interact with Gala Launchpad directly:
claude mcp add "galachain-launchpad" -- env PRIVATE_KEY=<YOUR_PRIVATE_KEY> ENVIRONMENT=development npx -y @gala-chain/launchpad-mcp-server@latestEnvironment Variables:
PRIVATE_KEY- Your wallet private key (required)ENVIRONMENT- Backend environment:development|production(default: development)DEBUG- Enable debug logging:true|false(default: false)TIMEOUT- Request timeout in milliseconds (default: 30000)
Features: 50 tools + 14 slash commands for complete Gala Launchpad operations
Try slash commands (MCP v1.4.0+):
/galachain-launchpad:analyze-token tokenName=anime
/galachain-launchpad:portfolio
/galachain-launchpad:buy-tokens tokenName=anime galaAmount=100For AI Developers
Need help with SDK integration, trading bots, or MCP server development?
Ask @agent-galachain-launchpad-developer - a specialized AI agent with expertise in:
- Complete SDK API (45 methods)
- Trading patterns and DeFi best practices
- MCP server architecture
- Error handling strategies
- Performance optimization
Full Integration Guide: AI Agent Guide
Quick Start
Using Helper Functions (Recommended)
import { createLaunchpadSDK } from '@gala-chain/launchpad-sdk';
// Auto-detecting SDK creation (easiest method)
const sdk = createLaunchpadSDK({
wallet: 'your-private-key-or-mnemonic' // Auto-detects format!
});
// Clean, direct result access - All methods use options objects
// Pool Management - Direct result properties
const pools = await sdk.fetchPools({ type: 'recent', limit: 10 });
console.log(`Found ${pools.total} pools across ${pools.totalPages} pages`);
console.log(`Current page: ${pools.page}, Has next: ${pools.hasNext}`);
const badges = await sdk.fetchTokenBadges('dragnrkti');
console.log(`Volume badges: ${badges.volumeBadges.length}`);
console.log(`Engagement badges: ${badges.engagementBadges.length}`);
const details = await sdk.fetchPoolDetails('dragnrkti');
console.log(`Sale status: ${details.saleStatus}`);
console.log(`Native token quantity: ${details.nativeTokenQuantity}`);
// Price Calculations - Direct amount access
const buyAmount = await sdk.calculateBuyAmount({
tokenName: 'dragnrkti',
amount: '1', // 1 GALA
type: 'native'
});
console.log(`Buy amount: ${buyAmount.amount}`);
console.log(`Transaction fee: ${buyAmount.transactionFee}`);
// Trading Operations - Required expectedAmount and slippageToleranceFactor
const buyResult = await sdk.buy({
tokenName: 'dragnrkti',
amount: '1',
type: 'native',
expectedAmount: buyAmount.amount, // Required: from calculation
slippageToleranceFactor: 0.05 // Required: decimal format (5% slippage)
});
console.log(`Transaction ID: ${buyResult.transactionId}`);
// Data & Analytics - Clean pagination
const trades = await sdk.fetchTrades({ tokenName: 'dragnrkti' });
console.log(`Found ${trades.total} trades`);
console.log(`Page ${trades.page} of ${trades.totalPages}`);
trades.trades.forEach(trade => {
console.log(`Trade: ${trade.tradeType} ${trade.tokenAmount} at ${trade.createdAt.toISOString()}`);
});
const comments = await sdk.fetchComments({ tokenName: 'dragnrkti' });
console.log(`${comments.total} comments found`);
// User Operations - Direct balance access
const galaBalance = await sdk.fetchGalaBalance();
console.log(`GALA Balance: ${galaBalance.balance}`);
console.log(`Last updated: ${galaBalance.lastUpdated.toISOString()}`);
const tokenBalance = await sdk.fetchTokenBalance({
tokenName: 'dragnrkti',
address: sdk.getAddress()
});
console.log(`Token balance: ${tokenBalance.quantity}`);
console.log(`USD value: $${tokenBalance.holdingPriceUsd}`);
// Profile - Direct user data
const profile = await sdk.fetchProfile();
console.log(`Profile name: ${profile.fullName || 'Not set'}`);
// URL Utilities - Generate frontend URLs
const tokenUrl = sdk.getUrlByTokenName('dragnrkti');
console.log(`View token: ${tokenUrl}`);
// Output: https://lpad-frontend-test1.defi.gala.com/buy-sell/dragnrktiAuto-Pagination Feature
The SDK now supports automatic pagination for pool fetching with three powerful modes:
Three Pagination Modes
import { createLaunchpadSDK } from '@gala-chain/launchpad-sdk';
const sdk = createLaunchpadSDK({
wallet: 'your-private-key-or-mnemonic'
});
// MODE 1: Single Page (backward compatible)
// Limit <= 20: Single API call
const recent = await sdk.fetchPools({ type: 'recent', limit: 20 });
console.log(`Fetched ${recent.pools.length} pools in one request`);
// MODE 2: Multi-Page Auto-Fetch
// Limit > 20: Automatic concurrent multi-page fetching
const large = await sdk.fetchPools({ type: 'popular', limit: 100 });
console.log(`Fetched ${large.pools.length} pools across multiple pages`);
// Internally fetches 5 pages concurrently: 20+20+20+20+20 = 100 pools
// MODE 3: Infinite Fetch
// Limit = 0: Fetches ALL available pools
const all = await sdk.fetchPools({ limit: 0 });
console.log(`Fetched all ${all.pools.length} pools from the platform`);
// Convenience method for "fetch all" pattern
const allRecent = await sdk.fetchAllPools({ type: 'recent' });
console.log(`Total pools: ${allRecent.total}`);Concurrency Configuration
The SDK uses MAX_CONCURRENT_POOL_FETCHES to control parallel API requests:
import { MAX_CONCURRENT_POOL_FETCHES } from '@gala-chain/launchpad-sdk';
console.log(`SDK fetches up to ${MAX_CONCURRENT_POOL_FETCHES} pages concurrently`);
// Output: "SDK fetches up to 5 pages concurrently"Default: 5 concurrent requests Benefit: Balances speed with API rate limits
Performance Benefits
| Scenario | Pages Fetched | Network Calls | Time (Sequential) | Time (Concurrent) | Improvement |
|---|---|---|---|---|---|
| 20 pools | 1 page | 1 call | ~200ms | ~200ms | No change |
| 100 pools | 5 pages | 5 calls | ~1000ms | ~200ms | 5x faster |
| 500 pools | 25 pages | 25 calls | ~5000ms | ~1000ms | 5x faster |
| All pools (1000+) | 50+ pages | 50+ calls | ~10,000ms | ~2000ms | 5x faster |
When to Use Each Mode
Single Page (limit <= 20)
- Quick queries
- UI pagination with next/previous buttons
- When you only need recent results
Multi-Page (limit > 20)
- Analytics dashboards
- Bulk operations on specific token counts
- When you know how many results you need
Infinite (limit = 0 or fetchAllPools())
- Complete market scans
- Full portfolio analysis
- Trading bot initialization
- Data exports and backups
Example: Market Scanner
async function scanEntireMarket() {
// Fetch all pools at once (auto-pagination handles everything)
const allPools = await sdk.fetchAllPools({ type: 'popular' });
console.log(`Scanning ${allPools.total} pools...`);
// Filter for interesting opportunities
const highVolume = allPools.pools.filter(pool =>
parseFloat(pool.volumeGala) > 10000
);
console.log(`Found ${highVolume.length} high-volume pools`);
return highVolume;
}New Methods
fetchAllPools(options?)
Convenience method that automatically fetches all available pools:
// Fetch all recent pools
const allRecent = await sdk.fetchAllPools({ type: 'recent' });
// Fetch all pools matching search
const dragons = await sdk.fetchAllPools({ search: 'dragon' });
// Fetch specific token across all results
const specific = await sdk.fetchAllPools({ tokenName: 'anime' });
// Equivalent to fetchPools({ limit: 0 })
const all = await sdk.fetchAllPools();Manual SDK Creation (Alternative)
import { Wallet } from 'ethers';
import { LaunchpadSDK } from '@gala-chain/launchpad-sdk';
// Create wallet manually
const wallet = new Wallet(process.env.PRIVATE_KEY);
// Initialize SDK
const sdk = new LaunchpadSDK({
wallet: wallet,
baseUrl: 'https://lpad-backend-dev1.defi.gala.com',
timeout: 30000,
debug: false
});
// Same clean API available
const pools = await sdk.fetchPools({ type: 'recent' });
console.log(`${pools.total} pools found`);Complete Example: Trading Flow with Clean Results
import { createLaunchpadSDK } from '@gala-chain/launchpad-sdk';
// 1. Create SDK with auto-detection
const sdk = createLaunchpadSDK({
wallet: 'your-private-key-or-mnemonic'
});
// 2. Check available pools - direct access to results
const pools = await sdk.fetchPools({
type: 'recent',
limit: 10
});
console.log(`Found ${pools.total} pools across ${pools.totalPages} pages`);
pools.pools.forEach(pool => {
console.log(`Pool: ${pool.tokenName} created at ${pool.createdAt}`);
});
// 3. Get price quote - direct amount access
const quote = await sdk.calculateBuyAmount({
tokenName: 'tinyevil',
amount: '100',
type: 'native'
});
console.log(`Buying 100 GALA worth will get you: ${quote.amount} TINYEVIL`);
console.log(`Transaction fee: ${quote.transactionFee} GALA`);
console.log(`Reverse bonding curve fee: ${quote.reverseBondingCurveFee} GALA`);
// 4. Execute trade with slippage protection - requires expectedAmount
const buyResult = await sdk.buy({
tokenName: 'tinyevil',
amount: '100',
type: 'native',
expectedAmount: quote.amount, // Required: from calculation above
slippageToleranceFactor: 0.05 // Required: decimal format for 5% slippage
});
console.log(`Transaction submitted: ${buyResult.transactionId}`);
// 5. Check trade history - clean pagination
const trades = await sdk.fetchTrades({ tokenName: 'tinyevil' });
console.log(`Found ${trades.total} trades on page ${trades.page}`);
console.log(`Has more pages: ${trades.hasNext}`);
trades.trades.forEach(trade => {
console.log(`${trade.tradeType}: ${trade.tokenAmount} at ${trade.createdAt.toISOString()}`);
});
// 6. Post a comment about your trade
const comment = await sdk.postComment({
tokenName: 'tinyevil',
content: 'Just bought some tokens! Great project!'
});
console.log(`Comment posted with ID: ${comment.id}`);
// 7. Check your balance - direct balance access
const galaBalance = await sdk.fetchGalaBalance();
console.log(`GALA Balance: ${galaBalance.balance}`);
console.log(`Decimals: ${galaBalance.decimals}`);
console.log(`Last updated: ${galaBalance.lastUpdated.toISOString()}`);
const tokenBalance = await sdk.fetchTokenBalance({
tokenName: 'tinyevil',
address: sdk.getAddress()
});
console.log(`TINYEVIL Balance: ${tokenBalance.quantity}`);
console.log(`USD Value: $${tokenBalance.holdingPriceUsd}`);
console.log(`GALA Value: ${tokenBalance.holdingPriceGala} GALA`);
console.log(`Finalized: ${tokenBalance.isFinalized}`);Transfer Operations
Transfer GALA and launchpad tokens between wallets with EIP-712 signatures:
import { createLaunchpadSDK } from '@gala-chain/launchpad-sdk';
const sdk = createLaunchpadSDK({
wallet: 'your-private-key-or-mnemonic'
});
// Transfer GALA tokens - direct result access
const galaTransfer = await sdk.transferGala({
recipientAddress: 'eth|1234567890abcdef1234567890abcdef12345678', // or 0x format
amount: '1', // 1 GALA
uniqueKey: 'galaconnect-operation-my-transfer-123' // Optional for idempotency
});
console.log(`GALA Transfer ID: ${galaTransfer.transactionId}`);
console.log(`Status: ${galaTransfer.status}`);
// Transfer launchpad tokens - direct result access
const tokenTransfer = await sdk.transferToken({
to: '0x9876543210fedcba9876543210fedcba98765432', // or eth| format
tokenName: 'tinyevil',
amount: '1000000', // Token amount in smallest unit
uniqueKey: 'galaconnect-operation-token-transfer-456' // Optional for idempotency
});
console.log(`Token Transfer ID: ${tokenTransfer.transactionId}`);
console.log(`Status: ${tokenTransfer.status}`);Transfer Features
- EIP-712 Signatures: Secure blockchain transactions
- Address Format Handling: Supports both
0xandeth|formats - Idempotency: Optional unique keys prevent duplicate transfers (must use
galaswap-operation-orgalaconnect-operation-prefix) - Comprehensive Validation: Amount limits, address formats, token names, unique key formats
- GalaChain Integration: Direct transfers via GalaChain gateway
- Error Handling: Detailed error types for different failure scenarios
Multi-Wallet Support
The SDK supports per-operation wallet overrides for testing multi-wallet workflows without creating new SDK instances. This is ideal for:
- Testing trading scenarios with multiple wallets
- Building multi-user applications
- Simulating different user behaviors
- Creating automated trading bots
Private Key Override Pattern
All signing operations accept an optional privateKey parameter to use a different wallet for that specific operation:
import { createLaunchpadSDK } from '@gala-chain/launchpad-sdk';
// Create SDK with your main wallet
const sdk = createLaunchpadSDK({
wallet: 'your-main-private-key'
});
// Different wallet's private key (must be in '0x' + 64 hex format)
const busterPrivateKey = '0x1234567890abcdef...'; // Buster's wallet
// 1. Send GALA from main wallet to Buster
await sdk.transferGala({
recipientAddress: '0xBusterAddress...',
amount: '1000'
// Uses main SDK wallet (no privateKey override)
});
// 2. Have Buster buy tokens using his own wallet
const buyResult = await sdk.buy({
tokenName: 'tinyevil',
amount: '100',
type: 'native',
expectedAmount: '500000',
slippageToleranceFactor: 0.05,
privateKey: busterPrivateKey // Override to use Buster's wallet
});
// 3. Have Buster post a comment
await sdk.postComment({
tokenName: 'tinyevil',
content: 'Great buy!',
privateKey: busterPrivateKey // Buster posts the comment
});
// 4. Main wallet continues operations normally
const mainWalletBalance = await sdk.fetchGalaBalance();
// Uses main SDK wallet addressSupported Operations with Private Key Override
All signing operations support the privateKey parameter:
Trading Operations:
buy(options)- Buy tokens with different walletsell(options)- Sell tokens with different wallet
Token Creation:
launchToken(data)- Create token from different walletuploadTokenImage(options)- Upload image for token
Transfer Operations:
transferGala(options)- Transfer GALA from different wallettransferToken(options)- Transfer tokens from different wallet
Social & Profile:
postComment(options)- Post comment from different walletupdateProfile(data)- Update profile for different walletuploadProfileImage(options)- Upload profile image for different wallet
Complete Multi-Wallet Example
import { createLaunchpadSDK, createWallet } from '@gala-chain/launchpad-sdk';
// Main SDK instance
const sdk = createLaunchpadSDK({
wallet: 'your-main-private-key'
});
// Create a test wallet for "Buster"
const busterWallet = createWallet(); // Random wallet
const busterPrivateKey = busterWallet.privateKey;
const busterAddress = busterWallet.address;
console.log(`Buster's address: ${busterAddress}`);
// 1. Fund Buster with GALA from main wallet
await sdk.transferGala({
recipientAddress: busterAddress,
amount: '1000'
});
// 2. Send Buster some tokens from main wallet
await sdk.transferToken({
to: busterAddress,
tokenName: 'tinyevil',
amount: '10000'
});
// 3. Have Buster send some tokens back to main wallet
await sdk.transferToken({
to: sdk.getEthereumAddress(), // Main wallet address
tokenName: 'tinyevil',
amount: '5000',
privateKey: busterPrivateKey // Buster's wallet signs
});
// 4. Have Buster buy more tokens
const buyQuote = await sdk.calculateBuyAmount({
tokenName: 'tinyevil',
amount: '100',
type: 'native'
});
await sdk.buy({
tokenName: 'tinyevil',
amount: '100',
type: 'native',
expectedAmount: buyQuote.amount,
slippageToleranceFactor: 0.05,
privateKey: busterPrivateKey // Buster buys
});
// 5. Have Buster sell some tokens
const sellQuote = await sdk.calculateSellAmount({
tokenName: 'tinyevil',
amount: '50',
type: 'native'
});
await sdk.sell({
tokenName: 'tinyevil',
amount: '50',
type: 'native',
expectedAmount: sellQuote.amount,
slippageToleranceFactor: 0.05,
privateKey: busterPrivateKey // Buster sells
});
// 6. Check final balances for both wallets
const mainBalance = await sdk.fetchGalaBalance(); // Main wallet
const busterBalance = await sdk.fetchGalaBalance(busterAddress); // Buster's wallet
console.log(`Main wallet: ${mainBalance.balance} GALA`);
console.log(`Buster wallet: ${busterBalance.balance} GALA`);Private Key Format Requirements
The privateKey parameter must be a string in the format:
- Format:
'0x' + 64 hexadecimal characters - Example:
'0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef' - Invalid: Raw hex without '0x' prefix, mnemonic phrases, addresses
// ✅ Valid private key formats
const validKey1 = '0x' + 'a'.repeat(64); // Correct format
const validKey2 = wallet.privateKey; // From ethers.js Wallet
// ❌ Invalid formats (will throw validation error)
const invalidKey1 = 'a'.repeat(64); // Missing '0x' prefix
const invalidKey2 = 'word1 word2 ... word24'; // Mnemonic not accepted
const invalidKey3 = '0x123'; // Too shortAvailable Methods & Result Types
Fetch Operations
// Pool Management
fetchPools(options?): Promise<PoolsResult>
// Returns: { pools, page, limit, total, totalPages, hasNext, hasPrevious }
// Supports auto-pagination: limit <= 20 (single page), limit > 20 (multi-page), limit = 0 (all pools)
fetchAllPools(options?): Promise<PoolsResult>
// Returns: { pools, page, limit, total, totalPages, hasNext, hasPrevious }
// Convenience method that fetches ALL pools (equivalent to fetchPools({ limit: 0 }))
fetchTokenDistribution(tokenName): Promise<TokenDistributionResult>
// Returns: { holders, totalSupply, totalHolders, lastUpdated }
fetchTokenBadges(tokenName): Promise<TokenBadgesResult>
// Returns: { volumeBadges, engagementBadges }
fetchPoolDetails(tokenName): Promise<PoolDetailsData>
// Returns: { basePrice, maxSupply, saleStatus, nativeTokenQuantity, ... }
fetchVolumeData(options): Promise<GraphDataResult>
// Returns: { dataPoints }
// Trade & User Data
fetchTrades(options): Promise<TradesResult>
// Returns: { trades, page, limit, total, totalPages, hasNext, hasPrevious }
fetchGalaBalance(address?): Promise<GalaBalanceInfo>
// Returns: { userAddress, balance, decimals, lastUpdated }
fetchTokenBalance(options): Promise<TokenBalanceInfo>
// Returns: { quantity, holdingPriceUsd, holdingPriceGala, isFinalized, ... }
fetchComments(options): Promise<CommentsResult>
// Returns: { comments, page, limit, total, totalPages, hasNext, hasPrevious }
fetchProfile(address?): Promise<UserProfile>
// Returns: { fullName, profileImage, address, ... }
fetchLaunchTokenFee(): Promise<number>
// Returns: Current GALA fee required to launch a new token (e.g., 0.001)Calculate Operations
// Price Calculations
calculateBuyAmount(options): Promise<AmountCalculationResult>
// Returns: { amount, reverseBondingCurveFee, transactionFee }
calculateSellAmount(options): Promise<AmountCalculationResult>
// Returns: { amount, reverseBondingCurveFee, transactionFee }
calculateInitialBuyAmount(options): Promise<AmountCalculationResult>
// Returns: { amount, reverseBondingCurveFee, transactionFee }
calculateBuyAmountForGraduation(tokenName): Promise<AmountCalculationResult>
// Returns: { amount, reverseBondingCurveFee, transactionFee }
// Calculates exact GALA cost to buy all remaining tokens and graduate pool
// Local Calculations (Client-Side, No Network)
calculateBuyAmountLocal(options): Promise<AmountCalculationResult>
// Options: { tokenName, amount, type: 'native' | 'exact' }
// Returns: { amount, reverseBondingCurveFee: '0', transactionFee, gasFee }
// Instant buy calculation using local bonding curve formulas
calculateSellAmountLocal(options): Promise<AmountCalculationResult>
// Options: { tokenName, amount, type: 'native' | 'exact', maxSupply, minFeePortion, maxFeePortion }
// Returns: { amount, reverseBondingCurveFee, transactionFee, gasFee }
// Instant sell calculation with reverse bonding curve fees
// External Calculations (GalaChain Network)
calculateBuyAmountExternal(options): Promise<AmountCalculationResult>
// Explicit external calculation wrapper (same as calculateBuyAmount)
calculateSellAmountExternal(options): Promise<AmountCalculationResult>
// Explicit external calculation wrapper (same as calculateSellAmount)
// Note: Pass `calculateAmountMode: 'local' | 'external'` to override SDK default mode
// Price History Operations (MySQL-based, Node.js only)
fetchPriceHistory(options): Promise<PriceHistoryResult>
// Options: { tokenId, from?, to?, sortOrder?, page?, limit? }
// Returns: { snapshots, page, limit, total, totalPages, hasNext, hasPrevious }
// Fetches paginated historical price snapshots from MySQL database
fetchAllPriceHistory(options): Promise<PriceHistoryResult>
// Options: { tokenId, from?, to?, sortOrder? } (no pagination params)
// Returns: All matching snapshots with total count
// Convenience method with automatic pagination (returns ALL snapshots)
fetchPrices(options?): Promise<PricesResult>
// Options: { page?, limit?, sortByType? }
// Returns: { snapshots, page, limit, total, totalPages, hasNext, hasPrevious }
// Fetches latest price for each unique token (paginated)
fetchAllPrices(): Promise<PricesResult>
// No parameters
// Returns: All latest prices combined in single result
// Convenience method with automatic pagination (returns ALL latest prices)
// Note: Price history methods require MySQL connection string in SDK config
// See MySQL Configuration section below for setup detailsPerformance Optimization
Reusing Pool Data to Avoid Redundant Network Calls
Methods that internally use calculateBuyAmount/calculateSellAmount now support optional calculateAmountMode and currentSupply parameters for performance optimization. This allows you to:
- Fetch pool details once using
fetchPoolDetailsForCalculation - Reuse
currentSupplyacross multiple calculations - Eliminate redundant network calls with local mode calculations
- Get instant results when real-time precision isn't required
Supported Methods
The following methods accept optional performance parameters:
fetchLaunchpadTokenSpotPrice(options)- PasscalculateAmountModeand/orcurrentSupplycalculateBuyAmountForGraduation(options)- PasscalculateAmountModeand/orcurrentSupplygraduateToken(options)- PasscalculateAmountModeand/orcurrentSupply
Using CALCULATION_MODES Constant
import { createLaunchpadSDK, CALCULATION_MODES } from '@gala-chain/launchpad-sdk';
const sdk = createLaunchpadSDK({
wallet: 'your-private-key-or-mnemonic'
});
// Use type-safe calculation mode constants
console.log(CALCULATION_MODES.LOCAL); // 'local'
console.log(CALCULATION_MODES.EXTERNAL); // 'external'Basic Optimization Pattern
import { createLaunchpadSDK, CALCULATION_MODES } from '@gala-chain/launchpad-sdk';
const sdk = createLaunchpadSDK({
wallet: 'your-private-key-or-mnemonic'
});
const tokenName = 'tinyevil';
// ❌ WITHOUT OPTIMIZATION (3 network calls)
const spotPrice1 = await sdk.fetchLaunchpadTokenSpotPrice(tokenName);
// → Fetches pool details internally (call #1)
const graduation1 = await sdk.calculateBuyAmountForGraduation(tokenName);
// → Fetches pool details internally (call #2)
const graduationResult1 = await sdk.graduateToken({ tokenName });
// → Fetches pool details internally (call #3)
// ✅ WITH OPTIMIZATION (1 network call + instant local calculations)
// Step 1: Fetch pool details once
const poolDetails = await sdk.fetchPoolDetailsForCalculation(tokenName);
const currentSupply = poolDetails.currentSupply; // Pre-computed with full precision
// Step 2: Reuse currentSupply for instant local calculations
const spotPrice2 = await sdk.fetchLaunchpadTokenSpotPrice({
tokenName,
calculateAmountMode: CALCULATION_MODES.LOCAL,
currentSupply
});
// → Uses local bonding curve formulas (instant, no network call)
const graduation2 = await sdk.calculateBuyAmountForGraduation({
tokenName,
calculateAmountMode: CALCULATION_MODES.LOCAL,
currentSupply
});
// → Uses local calculation (instant, no network call)
// Step 3: Graduate with optimized calculation
const graduationResult2 = await sdk.graduateToken({
tokenName,
calculateAmountMode: CALCULATION_MODES.LOCAL,
currentSupply,
slippageToleranceFactor: 0.01
});
// → Skips redundant pool fetch, uses local calculationPerformance Comparison
| Pattern | Network Calls | Speed | Use Case |
|---|---|---|---|
| Without Optimization | 3 calls | ~600-900ms | One-off operations |
| With Optimization | 1 call | ~200ms | Batch operations, price discovery |
| Reduction | 66% fewer calls | ~70% faster |
Complete Optimization Example
import { createLaunchpadSDK, CALCULATION_MODES } from '@gala-chain/launchpad-sdk';
const sdk = createLaunchpadSDK({
wallet: 'your-private-key-or-mnemonic'
});
async function optimizedPoolAnalysis(tokenName: string) {
console.time('Optimized Analysis');
// 1. Fetch pool details once (only network call needed)
const poolDetails = await sdk.fetchPoolDetailsForCalculation(tokenName);
const {
currentSupply,
maxSupply,
reverseBondingCurveMinFeeFactor,
reverseBondingCurveMaxFeeFactor
} = poolDetails;
// 2. Get spot price with local calculation (instant)
const spotPrice = await sdk.fetchLaunchpadTokenSpotPrice({
tokenName,
calculateAmountMode: CALCULATION_MODES.LOCAL,
currentSupply
});
console.log(`Spot price: $${spotPrice.usdPrice.toFixed(6)}`);
// 3. Calculate graduation cost with local calculation (instant)
const graduationCost = await sdk.calculateBuyAmountForGraduation({
tokenName,
calculateAmountMode: CALCULATION_MODES.LOCAL,
currentSupply
});
console.log(`Graduation cost: ${graduationCost.amount} GALA`);
// 4. Simulate multiple buy scenarios (all instant)
const buyAmounts = ['10', '100', '1000'];
for (const amount of buyAmounts) {
const buyCalc = await sdk.calculateBuyAmount({
tokenName,
amount,
type: 'native',
mode: CALCULATION_MODES.LOCAL, // Can also use 'mode' alias
currentSupply
});
console.log(`Buying ${amount} GALA gets you: ${buyCalc.amount} tokens`);
}
// 5. Simulate multiple sell scenarios (all instant)
const sellAmounts = ['10', '100', '1000'];
for (const amount of sellAmounts) {
const sellCalc = await sdk.calculateSellAmountLocal({
tokenName,
amount,
type: 'native',
maxSupply,
reverseBondingCurveMinFeeFactor,
reverseBondingCurveMaxFeeFactor
});
console.log(`Selling ${amount} GALA worth gets you: ${sellCalc.amount} GALA`);
}
console.timeEnd('Optimized Analysis');
// Output: Optimized Analysis: ~200-300ms (vs ~2-3 seconds without optimization)
}
optimizedPoolAnalysis('tinyevil');When to Use Optimization
✅ Use optimization when:
- Performing multiple calculations on the same token
- Building price discovery tools or analytics dashboards
- Running simulations or backtests
- Creating trading bots with frequent calculations
- Displaying real-time price feeds (use local mode for smooth updates)
❌ Skip optimization when:
- Performing a single calculation
- Requiring absolute precision from GalaChain network
- Token supply changes frequently between calls
Local vs External Calculations
// Local mode (client-side, instant, <0.01% difference from external)
const localCalc = await sdk.calculateBuyAmount({
tokenName: 'tinyevil',
amount: '100',
type: 'native',
mode: CALCULATION_MODES.LOCAL,
currentSupply: poolDetails.currentSupply
});
// External mode (GalaChain network, real-time, slower)
const externalCalc = await sdk.calculateBuyAmount({
tokenName: 'tinyevil',
amount: '100',
type: 'native',
mode: CALCULATION_MODES.EXTERNAL // or omit to use SDK default
});
// Accuracy comparison
const difference = Math.abs(
parseFloat(localCalc.amount) - parseFloat(externalCalc.amount)
);
const percentDiff = (difference / parseFloat(externalCalc.amount)) * 100;
console.log(`Difference: ${percentDiff.toFixed(4)}%`); // Typically < 0.01%SDK Configuration for Default Calculation Mode
import { createLaunchpadSDK, CALCULATION_MODES } from '@gala-chain/launchpad-sdk';
// Configure SDK to use local calculations by default
const sdk = createLaunchpadSDK({
wallet: 'your-private-key-or-mnemonic',
config: {
calculateAmountMode: CALCULATION_MODES.LOCAL // Default to local mode
}
});
// All calculations will use local mode by default
const calc1 = await sdk.calculateBuyAmount({
tokenName: 'tinyevil',
amount: '100',
type: 'native'
// Uses LOCAL mode from SDK config
});
// Override per-call if needed
const calc2 = await sdk.calculateBuyAmount({
tokenName: 'tinyevil',
amount: '100',
type: 'native',
mode: CALCULATION_MODES.EXTERNAL // Override to external for this call
});Token Metadata Cache
The SDK includes an intelligent metadata cache that eliminates redundant API calls and enables instant local calculations. The cache stores immutable token metadata (reverse bonding curve fees, vault addresses, max supply) that never changes.
How Cache Warming Works
Opportunistic & Zero-Cost: Cache warming happens automatically during normal SDK operations without any additional network requests. When you call fetchPools(), the SDK extracts and caches metadata from the pool data that was already fetched.
import { createLaunchpadSDK } from '@gala-chain/launchpad-sdk';
const sdk = createLaunchpadSDK({
wallet: 'your-private-key-or-mnemonic'
});
// Before fetching - cache is empty
let cacheInfo = sdk.getCacheInfo();
console.log('Cached tokens:', cacheInfo.totalTokens); // 0
// Fetch pools - automatically warms cache with RBC fees and vault addresses
await sdk.fetchPools({ type: 'recent', limit: 20 });
// After fetching - cache is warmed with 20 tokens
cacheInfo = sdk.getCacheInfo();
console.log('Cached tokens:', cacheInfo.totalTokens); // 20
console.log('Cache size:', (cacheInfo.cacheSize / 1024).toFixed(2), 'KB');
// Now local calculations are instant (no network calls required)
const calc = await sdk.calculateBuyAmountLocal({
tokenName: 'anime',
amount: '100',
type: 'native',
currentSupply: '500000'
});
console.log('Instant result:', calc.amount); // <1ms, used cached RBC feesPerformance Benefits
Dramatic Performance Improvements:
| Operation | Without Cache | With Cache | Improvement |
|---|---|---|---|
| Single calculation | ~200ms | <1ms | 200x faster |
| 10 calculations | ~2000ms | <5ms | 400x faster |
| Price discovery (50 tokens) | ~10,000ms | ~50ms | 200x faster |
Zero Network Overhead: Cache warming extracts metadata from pool responses you're already receiving - no extra API calls required.
Memory Efficient:
- ~220 bytes per cached token (includes RBC fees + vault address)
- Max 10,000 tokens = ~2.5 MB total memory
- LRU eviction keeps memory bounded
Cache Lifecycle
Session Lifetime:
- Cache persists for entire MCP server session (survives across conversations)
- For direct SDK usage, cache lifetime matches SDK instance lifetime
- Call
sdk.cleanup()to clear cache and release resources
LRU Eviction:
- Maximum 10,000 tokens cached
- Least Recently Updated (LRU) tokens evicted when limit reached
- O(1) get/set/eviction using JavaScript Map insertion order
// Cache automatically manages size
await sdk.fetchPools({ limit: 100 }); // Warms cache with 100 tokens
await sdk.fetchPools({ limit: 100 }); // Warms with 100 more tokens
await sdk.fetchPools({ limit: 100 }); // ... continues
// When 10,000 limit reached, oldest tokens are evicted automatically
const stats = sdk.getCacheInfo();
console.log('Total tokens:', stats.totalTokens); // Never exceeds 10,000
console.log('Oldest entry:', new Date(stats.oldestEntry).toISOString());Cache Management API
Get Cache Statistics:
const stats = sdk.getCacheInfo();
console.log('Total tokens cached:', stats.totalTokens);
console.log('Memory usage:', stats.cacheSize, 'bytes');
console.log('Average per entry:', (stats.cacheSize / stats.totalTokens).toFixed(0), 'bytes');
console.log('Oldest entry:', new Date(stats.oldestEntry).toISOString());Clear Cache (Selective or Complete):
// Clear specific token
sdk.clearCache('anime');
console.log('Cleared anime from cache');
// Clear all tokens
sdk.clearCache();
console.log('Cleared entire cache');
// Verify cache is empty
const stats = sdk.getCacheInfo();
console.log('Tokens remaining:', stats.totalTokens); // 0Manual Cache Warming (Advanced):
// Manually warm cache from pool data (useful for custom caching scenarios)
sdk.warmCacheFromPoolData('mytoken', {
vaultAddress: 'service|Token$Unit$MYTOKEN$...',
reverseBondingCurveMinFeeFactor: 0.0,
reverseBondingCurveMaxFeeFactor: 0.5
});
// Cache is now warmed for local calculations
const calc = await sdk.calculateBuyAmountLocal({
tokenName: 'mytoken',
amount: '100',
type: 'native',
currentSupply: '1000000'
});Complete Cache Example
import { createLaunchpadSDK, CALCULATION_MODES } from '@gala-chain/launchpad-sdk';
const sdk = createLaunchpadSDK({
wallet: 'your-private-key-or-mnemonic'
});
// 1. Warm cache by fetching pools
console.log('Warming cache...');
await sdk.fetchPools({ type: 'popular', limit: 50 });
// 2. Check cache statistics
const stats = sdk.getCacheInfo();
console.log(`Cache warmed with ${stats.totalTokens} tokens`);
console.log(`Memory: ${(stats.cacheSize / 1024).toFixed(2)} KB`);
// 3. 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) {
// Get pool details once for this token
const poolDetails = await sdk.fetchPoolDetailsForCalculation(token);
// Multiple instant calculations using cached data
const [buy10, buy100, buy1000] = await Promise.all([
sdk.calculateBuyAmountLocal({
tokenName: token,
amount: '10',
type: 'native',
currentSupply: poolDetails.currentSupply
}),
sdk.calculateBuyAmountLocal({
tokenName: token,
amount: '100',
type: 'native',
currentSupply: poolDetails.currentSupply
}),
sdk.calculateBuyAmountLocal({
tokenName: token,
amount: '1000',
type: 'native',
currentSupply: poolDetails.currentSupply
})
]);
console.log(`${token}:`);
console.log(` 10 GALA → ${buy10.amount} tokens`);
console.log(` 100 GALA → ${buy100.amount} tokens`);
console.log(` 1000 GALA → ${buy1000.amount} tokens`);
}
console.timeEnd('Batch Calculations');
// Output: Batch Calculations: ~50-100ms (vs ~3-5 seconds without cache)
// 4. Clear cache when done (optional)
sdk.clearCache();
console.log('\nCache cleared');Cache Design Philosophy
Immutable Data Only: Only caches data that never changes:
- ✅ Reverse bonding curve fee factors (set at token creation)
- ✅ Vault addresses (permanent token identifiers)
- ✅ Max supply (bonding curve constant, typically 10M)
- ❌ Current supply (changes with every trade - fetched dynamically)
- ❌ Token balances (user-specific and dynamic)
Zero-Cost Architecture: No extra API calls required for cache warming. Metadata is extracted from responses you're already receiving during normal operations.
Bounded Memory: LRU eviction ensures cache never exceeds 10,000 tokens (~2.5 MB), making it safe for long-running applications.
Smart Defaults: Uses 10,000,000 as default max supply for tokens without explicit data (matches 99%+ of launchpad tokens).
When to Use the Cache
✅ Perfect for:
- Price discovery and analytics dashboards
- Trading bots with frequent calculations
- Batch operations on multiple tokens
- Real-time price feeds and charts
- Simulation and backtesting tools
❌ Not needed for:
- Single one-off calculations
- Operations requiring absolute real-time precision
- Scenarios where current supply changes between calls
Cache Warming Demo
Run the complete cache demo to see all features in action:
npm run demo-cacheThe demo showcases:
- Opportunistic warming from
fetchPools() - Detailed warming from
fetchPoolDetailsForCalculation() - Token name normalization (case-insensitive)
- Cache hit performance (200x+ faster than network calls)
- Memory estimation accuracy
- LRU eviction behavior
- Clear cache operations
Trading Operations
// Buy/Sell Tokens
buy(options): Promise<TransactionResult>
// Options: { tokenName, amount, type, expectedAmount, slippageToleranceFactor }
// Returns: { transactionId, status, ... }
sell(options): Promise<TransactionResult>
// Options: { tokenName, amount, type, expectedAmount, slippageToleranceFactor }
// Returns: { transactionId, status, ... }
graduateToken(options): Promise<TransactionResult>
// Options: { tokenName, slippageToleranceFactor?, maxAcceptableReverseBondingCurveFeeSlippageFactor?, privateKey? }
// Returns: { transactionId, status, ... }
// One-step pool graduation: calculates cost and buys all remaining tokensContent Operations
// Comments & Content
postComment(options): Promise<CommentResult>
// Returns: { id, content, createdAt, ... }
// Token Creation & Management
launchToken(data): Promise<LaunchTokenResult>
// Returns: { transactionId, status, ... }
uploadTokenImage(options): Promise<ImageUploadResult>
// Returns: { imageUrl, success, ... }
// Profile Management
updateProfile(data): Promise<ProfileUpdateResult>
// Returns: { success, data, ... }
uploadProfileImage(options): Promise<ImageUploadResult>
// Returns: { imageUrl, success, ... }Validation & Utilities
isTokenNameAvailable(tokenName: string): Promise<boolean>isTokenSymbolAvailable(symbol: string): Promise<boolean>isTokenGraduated(tokenName: string): Promise<boolean>- Check if token completed bonding curve phasegetAddress(): string- Get backend format address (eth|...)getEthereumAddress(): string- Get Ethereum format address (0x...)getUrlByTokenName(tokenName: string): string- Get frontend URL for tokenresolveVaultAddress(tokenName: string): Promise<string>cleanup(): void- Cleanup resources
Configuration
Constants
import { MAX_CONCURRENT_POOL_FETCHES } from '@gala-chain/launchpad-sdk';
console.log(`SDK fetches up to ${MAX_CONCURRENT_POOL_FETCHES} pages concurrently`);
// Output: "SDK fetches up to 5 pages concurrently"MAX_CONCURRENT_POOL_FETCHES
- Type:
number - Value:
5 - Purpose: Controls concurrency for parallel page fetching in auto-pagination
- Balances: Speed vs API rate limits
- Usage: Exported constant for reference (not configurable at runtime)
SDK Configuration
interface LaunchpadSDKConfig {
wallet: Wallet; // ethers.js Wallet instance
baseUrl?: string; // Backend URL (default: dev environment)
galaChainBaseUrl?: string; // GalaChain gateway URL
bundleBaseUrl?: string; // Bundle service URL
webSocketUrl?: string; // WebSocket URL for monitoring
timeout?: number; // Request timeout (default: 30000ms)
debug?: boolean; // Enable debug logging
maxRetries?: number; // Retry attempts (default: 3)
retryDelay?: number; // Retry delay (default: 1000ms)
mysqlConnectionString?: string; // MySQL connection string for price history (Node.js only)
// Format: mysql://user:password@host:port/database
}MySQL Configuration (Price History)
To use the price history methods, you need to configure a MySQL connection string:
import { createLaunchpadSDK } from '@gala-chain/launchpad-sdk';
const sdk = createLaunchpadSDK({
wallet: 'your-private-key',
config: {
baseUrl: 'https://lpad-backend-dev1.defi.gala.com',
mysqlConnectionString: 'mysql://user:password@localhost:3306/galachain'
}
});
// 1. Fetch historical price snapshots (paginated)
const priceHistory = await sdk.fetchPriceHistory({
tokenId: 'Token|Unit|GUSDC|eth:9401b171307bE656f00F9e18DF756643FD3a91dE', // String format
from: new Date('2024-01-01'),
to: new Date('2024-01-31'),
sortOrder: 'DESC',
page: 1,
limit: 20
});
console.log(`Found ${priceHistory.snapshots.length} snapshots`);
console.log(`Total: ${priceHistory.total}, Page ${priceHistory.page} of ${priceHistory.totalPages}`);
// 2. Fetch ALL historical price snapshots (auto-paginated)
const allHistory = await sdk.fetchAllPriceHistory({
tokenId: { // Object format also supported
collection: 'Token',
category: 'Unit',
type: 'GUSDC',
additionalKey: 'eth:9401b171307bE656f00F9e18DF756643FD3a91dE'
},
from: new Date('2024-01-01'),
to: new Date('2024-01-31')
});
console.log(`Total snapshots: ${allHistory.total}`);
// 3. Fetch latest prices for all tokens (paginated)
const latestPrices = await sdk.fetchPrices({
page: 1,
limit: 20,
sortByType: 'ASC' // Optional: sort alphabetically by token type
});
console.log(`Found ${latestPrices.snapshots.length} tokens with prices`);
// 4. Fetch all latest prices (auto-paginated)
const allLatestPrices = await sdk.fetchAllPrices();
console.log(`Total tokens with prices: ${allLatestPrices.total}`);Token Identification Formats:
// String format (pipe-delimited) - simpler
tokenId: 'Token|Unit|GUSDC|eth:9401b171307bE656f00F9e18DF756643FD3a91dE'
// Object format (explicit) - for clarity
tokenId: {
collection: 'Token',
category: 'Unit',
type: 'GUSDC',
additionalKey: 'eth:9401b171307bE656f00F9e18DF756643FD3a91dE'
}Environment Configuration:
# Set in .env or pass to SDK config
PRICE_SERVICE_MYSQL_CONNECTION_STRING=mysql://user:password@localhost:3306/galachainRequirements:
- Node.js environment (browser not supported)
- MySQL server with
price_snapshotstable - Connection pooling is automatic (default 5 concurrent connections)
Security Considerations
⚠️ Credential Management:
- Store MySQL connection strings in environment variables, NOT in code
- Use restrictive file permissions on
.envfiles (recommended:0600) - Never log or expose connection strings in debug output
- For production, consider using credential providers (AWS Secrets Manager, Azure Key Vault, etc.)
⚠️ Input Validation:
- TokenClassKey fields are validated with a whitelist pattern to prevent SQL injection
- Only alphanumeric characters plus dots (.), colons (:), hyphens (-), and underscores (_) are allowed
- Fields are limited to 255 characters maximum
⚠️ Database Security:
- Ensure MySQL is behind a firewall and not exposed to the internet
- Use strong passwords and rotate them regularly
- Consider using SSL/TLS for MySQL connections in production
- Create a dedicated database user with read-only permissions (SELECT only)
- Built-in Read-Only Protection: This service enforces read-only mode at the MySQL session level, preventing any accidental or malicious write attempts. Even if the database user somehow gains write permissions, the session-level
read_onlyflag blocks all modifications.
⚠️ Column Type Requirements:
- Price column MUST be of type
DECIMAL(65,30)or similar high-precision type - Using
FLOATor other lossy types will cause precision loss with BigNumber operations - Verify your database schema matches the required types
Required Database Schema
The price_snapshots table must exist with the following schema:
CREATE TABLE `price_snapshots` (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY,
`collection` VARCHAR(255) NOT NULL,
`category` VARCHAR(255) NOT NULL,
`type` VARCHAR(255) NOT NULL,
`additional_key` VARCHAR(255) NOT NULL,
`price` DECIMAL(65, 30) NOT NULL,
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- Indexes for optimal query performance
INDEX `idx_token_lookup` (`collection`, `category`, `type`, `additional_key`),
INDEX `idx_created_at` (`created_at`),
INDEX `idx_token_date` (`collection`, `category`, `type`, `additional_key`, `created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;Schema Explanation:
id: Auto-incrementing primary key for unique row identificationcollection: Token collection identifier (e.g., "Token")category: Token category identifier (e.g., "Unit")type: Token type identifier (e.g., "GUSDC")additional_key: Additional token key for disambiguation (e.g., "eth:0x1234...")price: Token price as high-precision DECIMAL- CRITICAL: Use
DECIMAL(65, 30)for BigNumber compatibility - This provides 35 integer digits and 30 decimal places
- Sufficient for token prices ranging from satoshis to billions
- ⚠️ DO NOT USE: FLOAT, DOUBLE, or REAL (precision loss)
- CRITICAL: Use
created_at: Timestamp of price snapshot (defaults to insertion time)
Indexes:
idx_token_lookup: Composite index on token identifier fields for efficient filteringidx_created_at: Single index on creation timestamp for date range queriesidx_token_date: Composite index combining token fields and date for complex queries (recommended for high-volume databases)
Performance Tuning:
For high-volume price history databases (>10M snapshots):
-- Add partitioning by month
ALTER TABLE `price_snapshots`
PARTITION BY RANGE (MONTH(created_at)) (
PARTITION p202401 VALUES LESS THAN (202402),
PARTITION p202402 VALUES LESS THAN (202403),
-- ... more partitions
PARTITION p_future VALUES LESS THAN MAXVALUE
);
-- Consider archival strategy for old data
-- Archive snapshots older than 12 months to separate table
-- to maintain optimal query performanceValidation Checklist:
Before using fetchPriceHistory():
-
price_snapshotstable exists in your MySQL database - All columns match the schema above exactly
-
pricecolumn isDECIMAL(65, 30)(NOT FLOAT) - Indexes are created for query performance
- Database user has SELECT permissions on the table
- MySQL connection string is correct
- Test the connection:
SELECT COUNT(*) FROM price_snapshots LIMIT 1
Helper Functions
Wallet Creation
import { createWallet, validateWalletInput } from '@gala-chain/launchpad-sdk';
// Auto-detect format and create wallet
const wallet = createWallet('private-key-or-24-word-mnemonic');
const randomWallet = createWallet(); // Generate random wallet
// Validate input format without creating wallet
const isValid = validateWalletInput('0x1234...'); // booleanSDK Factory Functions
import { createLaunchpadSDK, createTestLaunchpadSDK } from '@gala-chain/launchpad-sdk';
// Main factory with auto-detection
const sdk = createLaunchpadSDK({
wallet: 'your-private-key-or-mnemonic',
config: {
baseUrl: 'https://lpad-backend-dev1.defi.gala.com',
debug: true
}
});
// Test-optimized SDK
const testSDK = createTestLaunchpadSDK({
wallet: 'test-private-key'
});Testing
# Run all tests
npm test
# Run integration tests (requires environment setup)
npm run test:integration
# Run type checking
npm run typecheck
# Run linting
npm run lintDocumentation
- SDK Method Reference - Complete flat API reference
- Clean Result Types Migration Guide - Migration guide for clean result types
- Service Architecture Migration Guide - Guide for v3.1.0 service-based architecture
- Price History Schema - Required MySQL schema for price history functionality
- API Documentation - Detailed API documentation
- Examples - Code examples and demos
Architecture
The SDK uses a service-based architecture with backend-aligned services:
Backend-Aligned Services
// Each service maps 1:1 to a specific backend
import {
LaunchpadService, // → launchpad-backend (pools, trades, comments, profiles)
GalaChainService, // → galachain-gateway (balances, transfers, pool details)
DexService, // → dex-api (spot prices)
BundleService, // → bundle-backend (transaction bundling, trading)
WebSocketService // → WebSocket endpoint (real-time monitoring)
} from '@gala-chain/launchpad-sdk';Service Responsibilities
LaunchpadService - Launchpad Backend Operations (Facade)
LaunchpadService uses a facade pattern internally, delegating to specialized sub-services:
// Internal architecture (v3.6.0+)
LaunchpadService (facade)
├── PoolService - Pool queries, distribution, badges, volume data
│ ├── fetchPools() - Supports auto-pagination (v3.11.0+)
│ ├── fetchAllPools() - Convenience method for limit: 0
│ └── ...other pool operations
├── TradeService - Trade history and queries
├── CommentService - Comments with vault resolution
├── UserService - Profile management and token lists
├── ImageService - Image upload operations
└── FaucetService - Faucet transfer operationsFacade Benefits:
- ✅ Single responsibility: Each sub-service has one clear purpose
- ✅ Maintainability: 76.8% reduction in main service file (1,657 → 384 lines)
- ✅ Code reuse: Shared utilities for query building and response normalization
- ✅ Backward compatibility: All public methods unchanged
- ✅ Testability: Sub-services can be tested independently
Public API (unchanged):
- Pool management (fetch, create, check) with auto-pagination
- Trade history
- Comments (post, fetch)
- User profiles
- Token images
- Faucet operations
GalaChainService - Blockchain Operations
- GALA balance queries
- Token balance queries
- Token transfers (GALA & launchpad tokens)
- Pool details from bonding curve contracts
- Token resolution
DexService - Price Queries
- Spot price fetching
- Multi-token price queries
BundleService - Transaction Bundling
- Buy token operations
- Sell token operations
- Slippage protection
- Transaction bundling
WebSocketService - Real-time Features
- Transaction monitoring
- Status updates
- Connection management
Benefits of Service Architecture
✅ Clear Separation: Each service has a single backend responsibility ✅ Type Safety: Full TypeScript support across all services ✅ Testability: Services can be tested independently ✅ Maintainability: Easy to locate and update backend-specific logic
AI Agent Integration
The SDK includes comprehensive utilities for AI agent development:
import { AgentConfig } from '@gala-chain/launchpad-sdk';
// Quick setup with intelligent defaults
const { sdk, validation } = await AgentConfig.quickSetup({
environment: 'development',
autoValidate: true
});
console.log(`Ready: ${validation.ready}`);
console.log(`Can trade: ${validation.capabilities.canTrade}`);For comprehensive AI agent integration, see:
- AI Agent Integration Guide - Complete guide for agent development
- MCP Tool Specification - Blueprint for MCP server creation
- Agent Examples - Working code examples
Clean Result Types Architecture
Key Benefits
✅ Direct Property Access: No more result.data.success chains
✅ Type Safety: Full TypeScript IntelliSense for all result properties
✅ Semantic Types: Dates as Date objects, numbers as numbers
✅ Computed Properties: hasNext, hasPrevious for convenience
✅ Zero Wrapper Overhead: Clean, direct access to all result data
✅ Options Object Pattern: All multi-parameter methods use options objects
Result Type Examples
// Pool results with pagination
interface PoolsResult {
pools: PoolData[]; // Direct pool array
page: number; // Current page
total: number; // Total items
hasNext: boolean; // Computed convenience
// ... more properties
}
// Token balance with typed values
interface TokenBalanceInfo {
quantity: string; // Token amount (string for precision)
holdingPriceUsd: number; // USD value (number for math)
lastUpdated: Date; // Date object (not string)
isFinalized: boolean; // Boolean flag
// ... more properties
}
// Trading results
interface AmountCalculationResult {
amount: string; // Calculated amount
transactionFee: string; // Fee breakdown
reverseBondingCurveFee: string; // RBC fee
// Direct access to all calculation data
}Environment URLs
- Development:
https://lpad-backend-dev1.defi.gala.com - Production:
https://lpad-backend-prod1.defi.gala.com
License
MIT License - see LICENSE file for details.
Contributing
Please read CONTRIBUTING.md for guidelines on contributing to this project.
Support
- GitHub Issues: Report bugs and request features
- Documentation: Full documentation and examples
- API Status: All 45 methods working and tested
Built with love for the Gala ecosystem