Building a token launch platform from scratch

I'm building Mauá, a token creation platform for the Brazilian market. Think pump.fun, but designed for Brazilians who want to launch tokens on Solana without touching code.
The idea is simple: anyone can create a token in two minutes, trade it immediately through an automated bonding curve, and if it gains enough traction, it graduates to a real DEX. No liquidity providers needed. No complex setup. Just name, symbol, image, and you're live.
Here's how I'm building it.
The core problem
Traditional token launches require liquidity. Someone has to put up capital to create a trading pair. This creates two problems: barrier to entry for creators, and rug pull risk for buyers when that liquidity gets pulled.
The solution is a bonding curve. Instead of a liquidity pool, the smart contract itself becomes the market maker. Price is determined mathematically based on supply. Buy tokens, price goes up. Sell tokens, price goes down. The formula is deterministic. No one can drain the liquidity because the liquidity is the contract.
When a token reaches a certain market cap threshold, it graduates. The contract automatically migrates the token to Raydium with real liquidity, and trading continues there.
Architecture decisions
I need four main pieces: smart contracts on Solana, a backend API, a TypeScript SDK, and a frontend.
For the smart contracts, I'm using Anchor. It's the standard framework for Solana development, and it gives me type safety and a clean IDL that I can use to generate TypeScript bindings.
For the backend, I chose Rust with the Loco framework. This might seem like overkill for a web API, but I have my reasons. First, I'm already deep in Rust for the smart contracts, so context switching is minimal. Second, Loco is essentially Rails for Rust. It gives me the rapid prototyping speed of a batteries-included framework with the performance of a compiled language. Third, I want the option to add compute-heavy features later without reaching for a different stack.
The SDK is TypeScript. It wraps all the Solana interactions into clean functions: create token, buy, sell, migrate. It handles PDA derivation, transaction building, and event listening. The frontend doesn't need to know anything about Solana internals.
The frontend is Next.js 14 with Tailwind. App Router, server components where they make sense, client components for wallet interactions. Nothing fancy here. I want it to feel fast and work on mobile, because most Brazilian users will be on their phones.
The smart contract
The program has a few key instructions: initialize the factory, create token, buy tokens, sell tokens, migrate to Raydium, and update fees.
The factory account holds global state: fee rates, authority, total tokens created. Each token gets its own TokenInfo account with reserves, supply, graduation threshold, and metadata.
The bonding curve math is straightforward. Price increases quadratically with supply:
price = supply² × constant
When someone buys, I calculate how many tokens they get for their SOL based on the current point on the curve. When someone sells, I calculate how much SOL they get back. A 1% fee is taken on every transaction.
The critical security measures: all math uses checked operations to prevent overflow, PDA signing ensures only the program can move funds, and the graduation threshold is immutable after creation.
Events fire for everything: TokenCreated, TokensBought, TokensSold, TokenGraduated, TokenMigrated. The backend listens to these to keep the database in sync with on-chain state.
The backend
Loco gives me a Rails-like structure: controllers, models, views, workers, mailers. I'm using SeaORM for database access, which feels natural coming from ActiveRecord.
Authentication is magic link based. No passwords. User enters email, gets a link, clicks it, gets a JWT. Simple and secure.
The token endpoints are straightforward:
GET /api/tokensreturns active tokensGET /api/tokens/trendingreturns tokens sorted by recent volumeGET /api/tokens/graduatedreturns tokens that made it to RaydiumGET /api/tokens/:mintreturns a single token with calculated fieldsPOST /api/tokenscreates a new token (triggers the on-chain creation)GET /api/tokens/myreturns the authenticated user's tokens
The views calculate derived fields: current price from the bonding curve formula, market cap from price times supply, graduation progress as a percentage toward the threshold.
A background worker listens to Solana events and updates the database. When someone buys or sells through the contract, the worker catches the event and updates reserves. When a token graduates, it updates the status. This keeps the API fast because reads hit Postgres, not the blockchain.
The SDK
The SDK is the glue between the frontend and the blockchain. It exports typed functions that match the smart contract instructions:
await sdk.createToken({
name: "MyToken",
symbol: "MTK",
imageUri: "https://..."
});
await sdk.buyTokens({
mint: tokenMint,
solAmount: 0.1
});
await sdk.sellTokens({
mint: tokenMint,
tokenAmount: 1000
});It also exports calculation helpers: estimate tokens out for a given SOL input, estimate SOL out for a given token input, calculate current price, calculate fees. The frontend uses these to show users what they'll get before they sign.
Event listeners let the frontend subscribe to updates for a specific token. When someone else buys or sells, the UI updates in real time.
The frontend
The app has four main pages: home with a grid of tokens, individual token pages with charts and trading, a create flow, and a profile page.
The token grid shows live data from the backend. Trending tokens rotate in a carousel. Each card shows the token image, name, current price, and graduation progress.
The individual token page is where the action happens. A price chart, recent trades, holder distribution, and a trading panel. The trading panel connects to the user's wallet (Phantom, Solflare, etc.) and uses the SDK to execute buys and sells.
The create flow is multi-step: upload image, enter name and symbol, preview, confirm. I want this to feel dead simple. Two minutes from idea to live token.
Hooks abstract the data fetching: useTokens, useTrendingTokens, useToken. They hit the backend API and handle loading and error states. The components stay clean.
Deployment
I'm using Railway for hosting and GitHub Actions for CI/CD.
The monorepo structure caused some headaches. Railway kept trying to build from the repository root instead of the specific app directories. The fix was configuring the root directory in Railway's dashboard to point to apps/backend and apps/frontend respectively.
Each push to main triggers a workflow that deploys the changed service. Backend changes deploy the backend. Frontend changes deploy the frontend. Both get their own Railway service with their own environment variables.
The backend needs DATABASE_URL and REDIS_URL (Railway provides these when you add Postgres and Redis), plus JWT secrets, SMTP credentials for magic links, and Solana RPC configuration.
The frontend needs NEXT_PUBLIC_API_BASE pointing to the backend URL and Solana network configuration.
What's left
The smart contract needs to be audited before mainnet. I'm running on devnet while I iron out the edge cases.
The backend listener that syncs on-chain events to the database needs more work. Right now it handles the happy path. I need to add retry logic and handle reorgs gracefully.
The frontend needs wallet adapter integration for the actual trading flow. Right now the trading panel is mocked. The SDK is ready, I just need to wire it up.
And I need to figure out the onramp story. Brazilian users need to buy SOL with PIX to use the platform. That's a whole separate problem.
Why I'm building this
The token launch market is dominated by platforms that weren't built for Brazilians. The UX assumes English speakers. The payment rails assume you have easy access to crypto.
I want to build something that feels native. Portuguese UI. PIX integration. Mobile-first design. Content and community features that resonate with Brazilian internet culture.
The technical architecture is mostly solved. The bonding curve works. The contracts are secure. The backend is fast. The frontend is responsive.
Now it's about execution. Ship features, get users, iterate on feedback. The code is the easy part. Building something people actually want to use is the hard part.