The PumpMore API is currently in beta testing. We welcome your feedbackβplease share it with our team at t.me/pumpmorefun.
PumpMore API Developer Docs
Introduction
The PumpMore API provides access to token and trade data from the PumpMore smart contract across multiple chains. This API allows developers to retrieve information about tokens, their market data, and recent trades.
Base URL
The base URL for all API endpoints is:
javascript<https://api.pumpmore.fun/v1>
Authentication
By default, the API is open and does not require authentication. However, rate limiting is applied to all requests. If you need higher rate limits, please contact the PumpMore team for an API key.
When using an API key, include it in the
X-API-Key
header of your requests.Example:
javascriptX-API-Key: your_api_key_here
If you don't have an API key, you can still access the API with rate limiting applied.
Rate Limiting
By default, API calls are limited to 600 requests per minute. Custom rate limits may be applied to specific API keys.
Endpoints
1. Get Token Data
Retrieve data for a specific token.
javascriptGET /tokens/{chainId}/address/{pairIdOrTokenId}
Parameters:
chainId
: The ID of the blockchain network
pairIdOrTokenId
: The address of the token or pair
Example Request:
javascriptcurl "<https://api.pumpmore.fun/v1/tokens/10243/address/0x23cd16315de43b317FE76B06cC873d4FACFD4b51>"
Example Response:
json{ "url": "<https://pumpmore.fun/details/0x1234>...", "chainId": "10243", "dexId": "pumpmore", "pairAddress": "0x1234...", "baseToken": { "address": "0x1234...", "name": "Example Token", "symbol": "EXT" }, "quoteToken": { "address": "0xabcd...", "name": "XPAA", "symbol": "XPAA" }, "priceNative": "0.1", "priceUsd": "", "txns": { "allTime": { "count": "100" } }, "volume": { "allTime": { "volumeToken": "1000000000000000000000" } }, "priceChange": {}, "liquidity": { "liquidityToken": "5000000000000000000000" }, "fdv": "10000000000000000000000", "marketCap": "5000000000000000000000", "createdAt": "1677777777", "pumpmore": { "curveType": "linear", "curvePosition": "0.5", "marketcapThreshold": "11200000 XPAA" }, "profile": { "icon": "ipfs://Qm...", "description": "Example token description", "links": [ {"website": "<https://example.com>"}, {"twitter": "<https://twitter.com/example>"}, {"telegram": "<https://t.me/example>"} ] }, "pumpMoreDetails": { "creator": "0x5678...", "tradingOnPumpmore": true, "tradingOnThirdtrade": false, "migrationSuccessful": false }, "totalSupply": "10000000000000000000000" }
2. Get Tokens by View
Retrieve tokens based on a specific view (e.g., new, trending).
plain textGET /tokens/{chainId}/{viewId}
Parameters:
chainId
: The ID of the blockchain network
viewId
: The view type (e.g., "new", "finished")
page
(optional): Page number for pagination (default: 1)
pageSize
(optional): Number of items per page (default: 10)
Example Request:
javascriptcurl "<https://api.pumpmore.fun/v1/tokens/10243/new?page=1&pageSize=5>"
Example Response:
json[ { "url": "<https://pumpmore.fun/details/0x1234567890123456789012345678901234567890>", "chainId": "10243", "dexId": "pumpmore", "pairAddress": "0x1234567890123456789012345678901234567890", // ... (similar structure to the single token response) }, // ... (4 more token objects) ]
3. Get Latest Trades
Retrieve the latest trades for a specific token or all tokens.
javascriptGET /trades/{chainId}/{pairIdOrTokenId?}
Parameters:
chainId
: The ID of the blockchain network
pairIdOrTokenId
(optional): The address of the token or pair (if omitted, returns trades for all tokens)
page
(optional): Page number for pagination (default: 1)
pageSize
(optional): Number of items per page (default: 50)
tradeType
(optional): Filter by trade type ("buy" or "sell")
Example Request:
javascriptcurl "<https://api.pumpmore.fun/v1/trades/10243/0x23cd16315de43b317FE76B06cC873d4FACFD4b51>"
Example Response:
json[ { "tokenAddress": "0x1234...", "tradeAmount": "100.5", "tradeType": "buy", "timestamp": "2023-05-01T12:34:56Z", "txHash": "0xabcd...", "price": "0.1" }, // ... more trade objects ]
WebSocket Support
The API includes WebSocket support for real-time data. Connect to the WebSocket server at
wss://api.pumpmore.fun
. WebSocket access may be restricted based on your API key permissions.To use the WebSocket connection:
- Connect to the WebSocket server.
- Send your API key for authentication.
- Subscribe to specific events or data streams.
Example WebSocket usage:
javascriptconst ws = new WebSocket('wss://api.pumpmore.fun'); ws.onopen = () => { ws.send(JSON.stringify({ type: 'auth', apiKey: 'your_api_key_here' })); ws.send(JSON.stringify({ type: 'subscribe', event: 'trades', chainId: '10243' })); }; ws.onmessage = (event) => { const data = JSON.parse(event.data); console.log('Received:', data); };
Connecting to the WebSocket
Connect to the WebSocket server at:
javascriptwss://api.pumpmore.fun/ws
Authentication
After connecting, send an authentication message:
json{ "type": "auth", "apiKey": "your_api_key_here" }
Subscribing to Updates
To subscribe to updates for a specific token:
json{ "type": "subscribe", "chainId": "10243", "tokenAddress": "0x23cd16315de43b317FE76B06cC873d4FACFD4b51" }
Receiving Updates
You will receive real-time updates in the following format:
json{ "type": "update", "chainId": "10243", "tokenAddress": "0x23cd16315de43b317FE76B06cC873d4FACFD4b51", "data": { // Updated token data (similar to the GET token data response) } }
Unsubscribing
To unsubscribe from updates:
json{ "type": "unsubscribe", "chainId": "10243", "tokenAddress": "0x23cd16315de43b317FE76B06cC873d4FACFD4b51" }
This documentation covers the main endpoints and WebSocket functionality of the PumpMore API. For more detailed information or support, please contact the PumpMore team.
Error Handling
The API uses standard HTTP status codes to indicate the success or failure of requests. In case of an error, the response will include a JSON object with an
error
field describing the issue.Example error response:
json{ "error": "Token not found or not recognized by the PumpMore contract" }
Code References
For implementation details, you can refer to the following code blocks:
- API routes and endpoints:
javascript// Get a single token by address router.get('/tokens/:chainId/address/:pairIdOrTokenId', async (req, res) => { try { const { chainId, pairIdOrTokenId } = req.params; const tokenData = await getTokenData(chainId, pairIdOrTokenId); res.json(tokenData); } catch (error) { if (error.message.includes('execution reverted')) { res.status(404).json({ error: 'Token not found or not recognized by the PumpMore contract' }); } else { res.status(500).json({ error: 'An error occurred while fetching token data' }); } console.error('Error details:', error); } }); // Get tokens by view router.get('/tokens/:chainId/:viewId', async (req, res) => { try { const { chainId, viewId } = req.params; const { page = 1, pageSize = 10 } = req.query; const tokens = await getTokensByView(chainId, viewId, parseInt(page), parseInt(pageSize)); res.json(tokens); } catch (error) { console.error('Error fetching tokens:', error); res.status(500).json({ error: error.message }); } }); router.get('/trades/:chainId/:pairIdOrTokenId?', async (req, res) => { try { const { chainId, pairIdOrTokenId } = req.params; const trades = await getLatestTrades(chainId, pairIdOrTokenId); res.json(trades); } catch (error) { res.status(500).json({ error: error.message }); } });
- Token data retrieval:
javascriptasync function getTokenData(chainId, pairIdOrTokenId) { const chainInfo = getChainInfo(chainId); if (!chainInfo) { logger.error('Chain info not found for chainId:', chainId); throw new Error(`Chain info not found for chainId: ${chainId}`); } const parsedChainId = parseInt(chainId, 10); if (isNaN(parsedChainId)) { logger.error('Invalid chainId:', chainId); throw new Error(`Invalid chainId: ${chainId}`); } const provider = new ethers.providers.JsonRpcProvider(chainInfo.rpcUrl, parsedChainId); const contract = new ethers.Contract(chainInfo.contractAddress, PumpMoreABI, provider); try { logger.debug('Fetching data for chainId:', chainId, 'pairIdOrTokenId:', pairIdOrTokenId); const [marketData, tokenDetails, tokenInfo, tokenMetadata, migrationCompleted] = await Promise.all([ contract.getMarketData(pairIdOrTokenId), contract.getTokenDetails(pairIdOrTokenId), contract.getTokenInfo(pairIdOrTokenId), contract.getTokenMetadata(pairIdOrTokenId), contract.migrationCompleted(pairIdOrTokenId) ]); const xpaaAddress = await contract.XPAA(); logger.debug('Data fetched successfully'); const initialFDV = ethers.BigNumber.from("14000000000000000000000"); const marketcapThreshold = initialFDV.mul(80).div(100); // 80% of initial FDV return { url: `https://pumpmore.fun/details/${pairIdOrTokenId}`, chainId: chainId, dexId: "pumpmore", pairAddress: pairIdOrTokenId, baseToken: { address: pairIdOrTokenId, name: tokenMetadata.name || '', symbol: tokenMetadata.symbol || '' }, quoteToken: { address: xpaaAddress, name: "XPAA", symbol: "XPAA" }, priceNative: marketData.price.toString(), priceUsd: "", txns: { allTime: { count: marketData.totalTransactions.toString() } }, volume: { allTime: { volumeToken: marketData.tradeVolume.toString() } }, priceChange: {}, liquidity: { liquidityToken: marketData.marketCap.toString() }, fdv: marketData.fdv.toString(), marketCap: marketData.marketCap.toString(), createdAt: marketData.createdAt.toString(), pumpmore: { curveType: "linear", curvePosition: marketData.migrationPercentage ? (marketData.migrationPercentage.toNumber() / 100).toString() : '0', marketcapThreshold: ethers.utils.formatEther(marketcapThreshold) + " XPAA" }, profile: { icon: tokenDetails.image ? `ipfs://${tokenDetails.image}` : '', description: tokenDetails.description || '', links: [ { website: tokenDetails.website }, { twitter: tokenDetails.twitter }, { telegram: tokenDetails.telegram }, { youtube: tokenDetails.youtube } ].filter(link => Object.values(link)[0]) }, pumpMoreDetails: { creator: tokenInfo.extended[1] || '', tradingOnPumpmore: !tokenInfo.extended[4], tradingOnThirdtrade: tokenInfo.extended[4], migrationSuccessful: migrationCompleted }, totalSupply: tokenMetadata.totalSupply ? tokenMetadata.totalSupply.toString() : '0' }; } catch (error) { logger.error('Error fetching contract data:', error); throw new Error(`Failed to fetch token data from the contract: ${error.message}`); } }
- Trade history retrieval:
javascriptasync function getLatestTrades(chainId, pairIdOrTokenId = null, page = 1, pageSize = 50, tradeType = null) { logger.debug(`Getting latest trades for chainId: ${chainId}, pairIdOrTokenId: ${pairIdOrTokenId}, page: ${page}, pageSize: ${pageSize}, tradeType: ${tradeType}`); const cachedTrades = cache.get(cacheKey); if (cachedTrades) { logger.debug('Returning cached trades'); return cachedTrades; } const chainInfo = getChainInfo(chainId); if (!chainInfo) { throw new Error(`Chain info not found for chainId: ${chainId}`); } const provider = new ethers.providers.JsonRpcProvider(chainInfo.rpcUrl, parseInt(chainId)); const contract = new ethers.Contract(chainInfo.contractAddress, PumpMoreABI, provider); try { let trades = []; if (pairIdOrTokenId) { trades = await contract.getTradeHistory(pairIdOrTokenId, pageSize * page); trades = trades.map(trade => ({ ...trade, tokenAddress: pairIdOrTokenId })); } else { const allTokens = await contract.getAllTokens(); logger.debug(`Fetching trades for ${allTokens.length} tokens`); for (const token of allTokens.slice(0, 10)) { try { const tokenTrades = await contract.getTradeHistory(token, pageSize); trades.push(...tokenTrades.map(trade => ({ ...trade, tokenAddress: token }))); } catch (error) { logger.error(`Error fetching trades for token ${token}:`, error); } } } logger.debug(`Total trades fetched: ${trades.length}`); trades.sort((a, b) => b.timestamp.sub(a.timestamp)); trades = trades.slice((page - 1) * pageSize, page * pageSize); if (tradeType === 'buy' || tradeType === 'sell') { trades = trades.filter(trade => trade.isBuy === (tradeType === 'buy')); } const formattedTrades = trades.map(trade => ({ tokenAddress: trade.tokenAddress, tradeAmount: ethers.utils.formatEther(trade.tokenAmount), tradeType: trade.isBuy ? 'buy' : 'sell', timestamp: new Date(trade.timestamp.toNumber() * 1000).toISOString(), txHash: trade.transactionHash || '', price: ethers.utils.formatEther(trade.price) })); logger.debug(`Returning ${formattedTrades.length} formatted trades`); cache.set(cacheKey, formattedTrades, 60); // Cache for 1 minute return formattedTrades; } catch (error) { logger.error('Error fetching trade history:', error); throw new Error(`Failed to fetch trade history: ${error.message}`); } }
- WebSocket server setup:
javascriptconst wss = new WebSocket.Server({ server }); wss.on('connection', (ws, req) => { const apiKey = req.headers['x-api-key']; if (!apiKey || !apiKeys.has(apiKey) || !apiKeys.get(apiKey).websocketAccess) { ws.close(1008, 'Unauthorized'); return; } console.log('New WebSocket connection'); // Handle incoming messages ws.on('message', (message) => { console.log('Received:', message); // Implement WebSocket message handling logic here });
This documentation covers the main endpoints and WebSocket functionality of the PumpMore API. For more detailed information or support, please contact the PumpMore team.