A user-friendly dApp for quick token deployment on Stellar, targeting creators in Nigeria and emerging markets.
Features • Quick Start • User Guides • Documentation • Contributing • Roadmap
- Overview
- Features
- Architecture
- Tech Stack
- Getting Started
- Project Structure
- Smart Contracts
- Frontend Application
- Testing
- CI/CD
- Deployment
- Configuration
- API Reference
- Contributing
- Roadmap
- FAQ
- License
- Support
Stellar Token Deployer (Nova Launch) is a decentralized application that enables creators, entrepreneurs, and businesses in emerging markets to deploy custom tokens on the Stellar blockchain without writing a single line of code.
- 🎯 No Coding Required: Simple form-based interface for token deployment
- 💰 Low Fees: Leverage Stellar's ultra-low transaction costs (~0.00001 XLM)
- ⚡ Fast: Deploy tokens in seconds, not hours
- 🌍 Emerging Markets Focus: Optimized for users in Nigeria and other developing regions
- 🔒 Secure: Non-custodial, wallet-based authentication
- 📱 Mobile-First: Responsive design for all devices
- 📲 PWA Support: Install as an app on any device with offline capabilities
Pay minimal XLM fees to deploy and mint tokens directly to your wallet. Optional metadata (images, descriptions) can be added via IPFS for a small additional fee. All fees funnel to the platform treasury, creating a sustainable business model aligned with Stellar's cheap transaction model.
- ✅ Deploy custom tokens with configurable parameters
- ✅ Set token name, symbol, decimals, and initial supply
- ✅ Automatic minting to creator's wallet
- ✅ Admin-controlled post-deployment minting
- ✅ Fee collection to platform treasury
- ✅ Token registry for tracking deployments
- ✅ Wallet connection via Freighter
- ✅ Network switching (Testnet/Mainnet)
- ✅ Multi-step token deployment form
- ✅ Real-time input validation
- ✅ Fee calculation and breakdown
- ✅ Transaction history tracking
- ✅ Responsive, mobile-first design
- ✅ Accessibility compliant (WCAG 2.1)
- ✅ PWA support with offline mode
- ✅ Installable on mobile and desktop
- ✅ Optional IPFS metadata upload
- ✅ Token images and descriptions
- ✅ On-chain metadata URI storage
- ✅ Image validation and preview
- ✅ Comprehensive unit tests
- ✅ Property-based testing
- ✅ 27+ passing tests
- ✅ >80% code coverage
- ✅ TypeScript strict mode
- 🔄 Batch token deployment
- 📊 Token analytics dashboard
- 🔐 Pro tier (clawback, multi-sig)
- 🌐 Multi-wallet support
- 📱 Mobile app (iOS/Android)
- 🎨 Token templates
- 🔍 Token discovery marketplace
┌─────────────────────────────────────────────────────────────┐
│ Frontend (React/TS) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Token Deploy │ │ Wallet │ │ Transaction │ │
│ │ Form │ │ Connection │ │ History │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Integration Layer │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Stellar SDK │ │ Freighter │ │ IPFS │ │
│ │ │ │ Wallet │ │ (Pinata) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Stellar Network (Soroban) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Token Factory Contract (Rust) │ │
│ │ - create_token() │ │
│ │ - mint_tokens() │ │
│ │ - set_metadata() │ │
│ │ - collect_fees() │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
- User Input: User fills deployment form with token parameters
- Validation: Frontend validates all inputs client-side
- Metadata Upload (optional): Images uploaded to IPFS via Pinata
- Transaction Building: Stellar SDK builds contract invocation
- Wallet Signing: User signs transaction via Freighter
- Submission: Transaction submitted to Stellar network
- Confirmation: Monitor transaction status and confirmation
- Result: Display token address and transaction details
- History: Store deployment info in local storage
| Technology | Version | Purpose |
|---|---|---|
| Rust | 2021 | Smart contract language |
| Soroban SDK | 21.0.0 | Stellar smart contract framework |
| soroban-token-sdk | Latest | Token standard implementation |
| proptest | 1.4 | Property-based testing |
| Technology | Version | Purpose |
|---|---|---|
| React | 19.2.0 | UI framework |
| TypeScript | 5.9.3 | Type safety |
| Vite | 8.0.0-beta | Build tool |
| Tailwind CSS | 4.1.18 | Styling |
| Vitest | 4.0.18 | Testing framework |
| fast-check | 4.5.3 | Property-based testing |
| Service | Purpose |
|---|---|
| Stellar SDK | Blockchain interaction |
| Freighter | Wallet connection |
| Pinata | IPFS metadata storage |
| Horizon API | Transaction monitoring |
Before you begin, ensure you have the following installed:
- Node.js 18+ (Download)
- npm or yarn
- Rust 1.70+ (Install)
- Soroban CLI (Install Guide)
- Freighter Wallet (Chrome Extension)
- Clone the repository
git clone https://github.com/Emmyt24/Nova-launch.git
cd Nova-launch- Install frontend dependencies
cd frontend
npm install- Install Rust dependencies
cd ../contracts/token-factory
cargo build- Set up Soroban environment
# Run the setup script
chmod +x ../../scripts/setup-soroban.sh
../../scripts/setup-soroban.shThis script will:
- Install Rust and wasm32 target
- Install Soroban CLI
- Configure Stellar testnet
- Generate admin identity
- Provide funding instructions
The fastest way to run the full stack locally is with Docker Compose.
Prerequisites: Docker 24+ and Docker Compose v2.
# 1. Copy and configure environment variables
cp .env.example .env
# Edit .env — at minimum set JWT_SECRET and ADMIN_JWT_SECRET
# 2. Start all services (postgres, redis, backend, frontend)
docker compose up --build
# 3. Open the app
# Frontend → http://localhost:5173
# Backend → http://localhost:3001To stop and remove containers:
docker compose down
# Add -v to also remove the postgres volume (wipes database)
docker compose down -vServices started by Docker Compose:
| Service | Port | Description |
|---|---|---|
| postgres | 5432 | PostgreSQL 16 database |
| redis | 6379 | Redis 7 (rate limiter) |
| backend | 3001 | Express/Next.js API |
| frontend | 5173 | React/Vite app (served via nginx) |
Note:
VITE_*variables are baked into the frontend at build time. If you change them in.env, rebuild withdocker compose up --build frontend.
cd frontend
# Start development server
npm run dev
# Run tests
npm test
# Run tests with UI
npm run test:ui
# Build for production
npm run build
# Preview production build
npm run previewThe frontend will be available at http://localhost:5173
cd contracts/token-factory
# Build contract
cargo build --target wasm32-unknown-unknown --release
# Run tests
cargo test
# Optimize WASM (requires soroban-cli)
soroban contract optimize \
--wasm target/wasm32-unknown-unknown/release/token_factory.wasm# Quick deployment (recommended)
./scripts/deploy-testnet.sh
# This script will:
# - Verify admin identity
# - Create treasury identity if needed
# - Deploy the contract
# - Initialize with proper configuration
# - Save deployment info to deployment-testnet.json
# - Run basic smoke tests
# Verify deployment
./scripts/verify-deployment.sh
# Update frontend environment
./scripts/update-frontend-env.shFor detailed deployment instructions, see DEPLOYMENT_GUIDE.md.
For the end-to-end production deployment and post-deploy verification runbook, see docs/PRODUCTION_INTEGRATION_RUNBOOK.md.
nova-launch/
├── contracts/ # Smart contracts
│ ├── token-factory/ # Token factory contract
│ │ ├── src/
│ │ │ ├── lib.rs # Main contract logic
│ │ │ ├── types.rs # Data structures
│ │ │ ├── storage.rs # Storage management
│ │ │ └── test.rs # Contract tests
│ │ └── Cargo.toml
│ └── Cargo.toml # Workspace config
│
├── frontend/ # React frontend
│ ├── src/
│ │ ├── components/ # React components
│ │ │ ├── Layout/ # Layout components
│ │ │ ├── UI/ # Reusable UI components
│ │ │ ├── TokenDeployForm/
│ │ │ ├── WalletConnect/
│ │ │ └── TransactionHistory/
│ │ ├── services/ # API services
│ │ │ ├── stellar.ts # Stellar SDK integration
│ │ │ ├── wallet.ts # Wallet service
│ │ │ └── ipfs.ts # IPFS service
│ │ ├── hooks/ # Custom React hooks
│ │ ├── types/ # TypeScript types
│ │ ├── utils/ # Utility functions
│ │ ├── config/ # Configuration
│ │ ├── test/ # Test utilities
│ │ ├── App.tsx # Main app component
│ │ └── main.tsx # Entry point
│ ├── public/ # Static assets
│ ├── package.json
│ └── vite.config.ts
│
├── scripts/ # Utility scripts
│ └── setup-soroban.sh # Soroban setup script
│
├── .kiro/ # Kiro specs (excluded from git)
│ └── specs/
│ └── stellar-token-deployer/
│ ├── requirements.md
│ ├── design.md
│ └── tasks.md
│
├── .gitignore
└── README.md
The Token Factory is the core smart contract that handles token deployment and management.
Initialize the factory with admin, treasury, and fee structure.
pub fn initialize(
env: Env,
admin: Address,
treasury: Address,
base_fee: i128,
metadata_fee: i128,
) -> Result<(), Error>Deploy a new token with specified parameters.
pub fn create_token(
env: Env,
creator: Address,
name: String,
symbol: String,
decimals: u32,
initial_supply: i128,
fee_payment: i128,
) -> AddressAdd metadata URI to an existing token.
pub fn set_metadata(
env: Env,
token_address: Address,
admin: Address,
metadata_uri: String,
fee_payment: i128,
) -> Result<(), Error>Update the metadata URI for a token with full version tracking. Each call increments the on-chain version counter and records a permanent history entry.
pub fn update_metadata(
env: Env,
admin: Address,
token_index: u32,
new_metadata_uri: String,
) -> Result<u32, Error>Parameters:
admin: Token creator address (must authorize)token_index: Index of the token to updatenew_metadata_uri: New IPFS URI (e.g.,"ipfs://QmNewHash...")
Returns: The new version number (starts at 2 after the first update).
Errors:
MetadataNotSet(54) — metadata was never set; callset_token_metadatafirstUnauthorized— caller is not the token creatorTokenNotFound— token index does not existContractPaused— contract is paused
Events: Emits meta_upd with token address, admin, new URI, and version.
Retrieve a historical metadata record for a specific version.
pub fn get_metadata_history(
env: Env,
token_index: u32,
version: u32,
) -> Option<MetadataRecord>Returns: Some(MetadataRecord) if the version exists, None otherwise.
MetadataRecord fields:
uri: String— the metadata URI at that versionupdated_at: u64— ledger timestamp of the updateupdated_by: Address— address that performed the update
Mint additional tokens (admin only).
pub fn mint_tokens(
env: Env,
token_address: Address,
admin: Address,
to: Address,
amount: i128,
fee_payment: i128,
) -> Result<(), Error>Allows token holders to burn their own tokens, permanently removing them from circulation.
pub fn burn(
env: Env,
token_address: Address,
from: Address,
amount: i128,
) -> Result<(), Error>Parameters:
token_address: Address of the token contractfrom: Address of the token holder burning tokensamount: Amount of tokens to burn (in smallest unit)
Example:
// Burn 1000 tokens (with 7 decimals)
factory.burn(
&token_address,
&user_address,
&1000_0000000
);Allows token admin to burn tokens from any address (clawback).
pub fn admin_burn(
env: Env,
token_address: Address,
admin: Address,
from: Address,
amount: i128,
) -> Result<(), Error>Security Note: Only the token creator can perform admin burns.
Burn tokens from multiple addresses in a single transaction.
pub fn burn_batch(
env: Env,
token_address: Address,
burns: Vec<(Address, i128)>,
) -> Result<(), Error>Gas Optimization: More efficient than multiple individual burns.
Update fee structure (admin only).
pub fn update_fees(
env: Env,
admin: Address,
base_fee: Option<i128>,
metadata_fee: Option<i128>,
) -> Result<(), Error>Get current factory state.
pub fn get_state(env: Env) -> FactoryStateGet the current base fee for token deployment.
pub fn get_base_fee(env: Env) -> i128Returns the base fee amount in stroops that must be paid for any token deployment, regardless of metadata inclusion.
Get the current metadata fee for token deployment.
pub fn get_metadata_fee(env: Env) -> i128Returns the additional fee amount in stroops that must be paid when deploying a token with metadata (IPFS URI).
Get information about a deployed token.
pub fn get_token_info(
env: Env,
index: u32
) -> Result<TokenInfo, Error>| Code | Error | Description |
|---|---|---|
| 1 | InsufficientFee |
Fee payment is below minimum |
| 2 | Unauthorized |
Caller not authorized for action |
| 3 | InvalidParameters |
Invalid token parameters |
| 4 | TokenNotFound |
Token not found in registry |
| 5 | MetadataAlreadySet |
Metadata already set for token |
| 6 | AlreadyInitialized |
Factory already initialized |
| 7 | BurnAmountExceedsBalance |
Burn amount exceeds token balance |
| 8 | BurnNotEnabled |
Burn functionality not enabled |
| 9 | InvalidBurnAmount |
Burn amount is zero or negative |
| 54 | MetadataNotSet |
Metadata has never been set; call set_token_metadata first |
These codes are reserved for vault lifecycle failures and are guaranteed to remain stable for downstream clients.
| Code | Error | Description |
|---|---|---|
| 60 | VaultNotFound |
Referenced vault does not exist |
| 61 | VaultLocked |
Unlock time or milestone has not been met |
| 62 | VaultAlreadyClaimed |
Vault funds have already been claimed |
| 63 | VaultCancelled |
Vault was cancelled and is immutable |
| 64 | InvalidVaultConfig |
Vault parameters failed validation |
| 65 | NothingToClaim |
No claimable balance remains (vaults/streams) |
Emitted when tokens are burned.
Data:
token_address: Addressfrom: Addressamount: i128burned_by: Addresstimestamp: u64is_admin_burn: bool
Located in frontend/src/components/UI/:
- Button: Configurable button with variants and loading states
- Input: Form input with validation and error display
- Card: Content card with optional title
- Spinner: Loading spinner with size variants
- Tooltip: Contextual help tooltips
- Modal: Accessible modal dialogs
- Toast: Notification system
- Skeleton: Loading placeholders
- ErrorBoundary: Error handling wrapper
- Header: Application header with branding
- Container: Responsive content container
Handles all Stellar network interactions.
class StellarService {
constructor(network: "testnet" | "mainnet");
async deployToken(params: TokenDeployParams): Promise<DeploymentResult>;
async mintTokens(
tokenAddress: string,
recipient: string,
amount: string,
): Promise<string>;
async getTokenInfo(tokenAddress: string): Promise<TokenInfo>;
async getTransaction(hash: string): Promise<TransactionDetails>;
}Manages Freighter wallet connection.
class WalletService {
async connect(): Promise<string>;
disconnect(): void;
async signTransaction(xdr: string): Promise<string>;
async getBalance(address: string): Promise<string>;
isInstalled(): boolean;
}Handles metadata upload to IPFS.
class IPFSService {
async uploadMetadata(
image: File,
description: string,
tokenName: string,
): Promise<string>;
async getMetadata(uri: string): Promise<TokenMetadata>;
}Manages wallet connection state.
const {
wallet, // WalletState
connect, // () => Promise<void>
disconnect, // () => void
isConnecting, // boolean
error, // string | null
} = useWallet();Manages token deployment process.
const {
deploy, // (params: TokenDeployParams) => Promise<DeploymentResult>
isDeploying, // boolean
status, // DeploymentStatus
error, // AppError | null
} = useTokenDeploy();Manages toast notifications.
const {
toasts, // ToastState[]
success, // (message: string) => void
error, // (message: string) => void
info, // (message: string) => void
warning, // (message: string) => void
} = useToast();// Validate Stellar address
isValidStellarAddress(address: string): boolean
// Validate token parameters
validateTokenParams(params): { valid: boolean; errors: Record<string, string> }
// Validate image file
isValidImageFile(file: File): { valid: boolean; error?: string }// Format XLM amounts
formatXLM(amount: string | number): string
// Truncate addresses
truncateAddress(address: string, startChars?: number, endChars?: number): string
// Convert stroops to XLM
stroopsToXLM(stroops: number | string): number
// Convert XLM to stroops
xlmToStroops(xlm: number | string): numberUse the unified test runner for all test categories:
# Fast mode (2-5 min) - Local development
./scripts/run-tests.sh -m fast
# Full mode (10-15 min) - PR validation
./scripts/run-tests.sh -m full
# Nightly mode (30-60 min) - Comprehensive
./scripts/run-tests.sh -m nightlySee Test Runner Documentation for detailed usage.
# Frontend tests
cd frontend
npm test # Run all tests
npm run test:ui # Run with UI
npm run test:coverage # Generate coverage report
# Contract tests
cd contracts/token-factory
cargo test # Run all tests
cargo test -- --nocapture # Run with outputTests individual functions and modules in isolation.
cargo test --lib --testsTests interactions between components.
cargo test --test '*'Randomized testing for governance invariants:
- Monotonic vote totals
- Single-vote-per-address
- Execution preconditions
- Terminal state permanence
- Vote distribution consistency
cargo test --lib --profile ciPerformance testing (nightly mode only).
cargo bench --no-runThe frontend performance pipeline records bundle and Lighthouse metrics locally and can optionally publish sanitized custom events to New Relic.
cd frontend
npm run monitorTo enable the New Relic export path, set NEW_RELIC_ACCOUNT_ID and NEW_RELIC_INSERT_KEY before running the command. Optional overrides include NEW_RELIC_INSIGHTS_URL, NEW_RELIC_APP_NAME, and NEW_RELIC_SOURCE.
| Mode | Duration | Tests | Use Case |
|---|---|---|---|
| Fast | 2-5 min | Unit + Integration | Local dev, pre-commit |
| Full | 10-15 min | + Property tests | PR validation, CI |
| Nightly | 30-60 min | + Benchmarks + WASM | Release validation |
Tests run automatically on:
- Push: Fast mode
- Pull Request: Full mode
- Schedule: Nightly mode (2 AM UTC)
Current coverage: >80%
# Generate coverage report
cd frontend
npm run test:coverage
# View report
open coverage/index.htmlThe project uses GitHub Actions for automated testing and validation. All checks must pass before code can be merged.
- Rust Contract Tests: Formatting, linting, tests, and WASM build
- Frontend Tests: Linting, tests, and production build
- Security Audit: Dependency vulnerability scanning
- Spec Validation: Ensures all spec files are complete
Before pushing code, run the local CI validation:
./scripts/ci-check.shThis runs all CI checks locally to catch issues early.
Enable pre-commit hooks to catch issues before committing:
git config core.hooksPath .githooksThe hook checks Rust formatting, frontend/backend lint, type-checking, Prettier formatting, secret detection, and conventional commit message format — scoped to staged files only for speed.
For more details, see CI/CD Guide.
cd contracts/token-factory
# Build optimized WASM
cargo build --target wasm32-unknown-unknown --release
soroban contract optimize --wasm target/wasm32-unknown-unknown/release/token_factory.wasm
# Deploy
CONTRACT_ID=$(soroban contract deploy \
--wasm target/wasm32-unknown-unknown/release/token_factory.wasm \
--network testnet \
--source admin)
echo "Contract deployed: $CONTRACT_ID"
# Initialize
soroban contract invoke \
--id $CONTRACT_ID \
--network testnet \
--source admin \
-- initialize \
--admin $(soroban keys address admin) \
--treasury $(soroban keys address treasury) \
--base_fee 70000000 \
--metadata_fee 30000000# Same as testnet but use --network mainnet
# Ensure you have funded mainnet accountscd frontend
# Install Vercel CLI
npm i -g vercel
# Deploy
vercel
# Production deployment
vercel --prodcd frontend
# Build
npm run build
# Deploy dist/ folder to NetlifyCreate .env file in frontend/:
VITE_FACTORY_CONTRACT_ID=<your_contract_id>
VITE_NETWORK=testnet
VITE_IPFS_API_KEY=<your_pinata_api_key>
VITE_IPFS_API_SECRET=<your_pinata_api_secret>Edit frontend/src/config/stellar.ts:
export const STELLAR_CONFIG = {
network: import.meta.env.VITE_NETWORK || "testnet",
factoryContractId: import.meta.env.VITE_FACTORY_CONTRACT_ID || "",
testnet: {
networkPassphrase: "Test SDF Network ; September 2015",
horizonUrl: "https://horizon-testnet.stellar.org",
sorobanRpcUrl: "https://soroban-testnet.stellar.org",
},
mainnet: {
networkPassphrase: "Public Global Stellar Network ; September 2015",
horizonUrl: "https://horizon.stellar.org",
sorobanRpcUrl: "https://soroban-mainnet.stellar.org",
},
};Edit frontend/src/config/ipfs.ts:
export const IPFS_CONFIG = {
apiKey: import.meta.env.VITE_IPFS_API_KEY || "",
apiSecret: import.meta.env.VITE_IPFS_API_SECRET || "",
pinataApiUrl: "https://api.pinata.cloud",
pinataGateway: "https://gateway.pinata.cloud/ipfs",
};Default fees (in stroops, 1 XLM = 10,000,000 stroops):
| Tier | Features | Fee (XLM) | Fee (stroops) |
|---|---|---|---|
| Basic | Token deployment | 7 | 70,000,000 |
| Metadata | + IPFS metadata | +3 | +30,000,000 |
| Total | With metadata | 10 | 100,000,000 |
Fees can be updated by factory admin using update_fees function.
Currently, all interactions are direct with the blockchain via Stellar SDK.
Future versions will include a GraphQL API for:
- Token discovery
- Analytics
- User profiles
- Transaction history
We welcome contributions from the community! Please see our Contributing Guidelines for details.
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Write/update tests
- Ensure tests pass:
npm test - Commit your changes:
git commit -m 'feat: add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Open a Pull Request
- Follow existing code style
- Write TypeScript with strict mode
- Add JSDoc comments for public APIs
- Include unit tests for new features
- Update documentation as needed
- Maintain >80% code coverage
We follow Conventional Commits:
feat: add new feature
fix: bug fix
docs: documentation changes
style: code style changes
refactor: code refactoring
test: test changes
chore: build/tooling changes
good first issue- Great for newcomersenhancement- New featurebug- Something isn't workingdocumentation- Documentation improvementshelp wanted- Extra attention needed
- Token Factory smart contract
- Basic frontend UI
- Wallet connection
- Token deployment
- Metadata upload
- Transaction history
- Testing infrastructure
- Wallet integration (Freighter, Albedo, xBull)
- Stellar SDK integration
- IPFS integration
- Multi-step deployment form
- Real-time fee calculation
- Transaction monitoring
- Mobile optimization
- Batch token deployment
- Token templates
- Analytics dashboard
- Token discovery marketplace
- Social features
- Multi-language support
- Clawback functionality
- Multi-sig support
- Advanced token management
- API access
- White-label solutions
- Enterprise features
- Mobile apps (iOS/Android)
- Token launchpad
- Liquidity pools integration
- DEX integration
- NFT support
- DAO governance
Q: What is Nova Launch?
A: Nova Launch is a no-code platform for deploying custom tokens on the Stellar blockchain.
Q: Do I need coding experience?
A: No! Nova Launch is designed for non-technical users.
Q: What are the fees?
A: Base deployment is 7 XLM, with an additional 3 XLM for metadata.
Q: Which networks are supported?
A: Both Stellar testnet (for testing) and mainnet (for production).