This guide covers deploying Stellar Ajo to production environments.
- Stellar Network account with XLM funds
- Vercel account for hosting
- GitHub account for code repository
- Domain name (optional but recommended)
# Navigate to contracts directory
cd contracts/ajo-circle
# Build the contract
cargo build --target wasm32-unknown-unknown --release
# Output location:
# target/wasm32-unknown-unknown/release/ajo_circle.wasm- Install Stellar CLI:
curl https://stellar.org/install | bash- Create a keypair (save in secure location):
stellar keys generate deployer- Fund the account with testnet XLM:
curl https://friendbot.stellar.org?addr=<PUBLIC_KEY>- Deploy the contract to testnet:
stellar contract deploy \
--wasm target/wasm32-unknown-unknown/release/ajo_circle.wasm \
--source deployer \
--network testnetThis will output the contract address. Save this value.
Create a deployment script scripts/deploy-contract.js:
import * as StellarSdk from 'stellar-sdk';
import * as fs from 'fs';
const network = StellarSdk.Networks.TESTNET_NETWORK_PASSPHRASE;
const rpcUrl = 'https://soroban-testnet.stellar.org';
const server = new StellarSdk.SorobanRpc.Server(rpcUrl);
// Load contract WASM
const wasmBuf = fs.readFileSync('./contracts/ajo-circle/target/wasm32-unknown-unknown/release/ajo_circle.wasm');
// Deploy logic here
// See: https://developers.stellar.org/docs/smart-contracts/guides/deploying-contractsSet these in your Vercel project settings:
NEXT_PUBLIC_STELLAR_NETWORK=mainnet
NEXT_PUBLIC_STELLAR_HORIZON_URL=https://horizon.stellar.org
NEXT_PUBLIC_STELLAR_NETWORK_PASSPHRASE=Public Global Stellar Network ; September 2015
NEXT_PUBLIC_SOROBAN_RPC_URL=https://soroban.stellar.org
NEXT_PUBLIC_AJO_CONTRACT_ADDRESS=<your-contract-address>
DATABASE_URL=<your-postgresql-connection-string>
JWT_SECRET=<generate-secure-random-string>
NEXT_PUBLIC_API_URL=https://your-domain.com/api
# Generate a cryptographically secure random string
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"For production, use PostgreSQL instead of SQLite:
- Create PostgreSQL database (e.g., with Vercel Postgres, AWS RDS, or Supabase)
- Set DATABASE_URL to your connection string
- Run migrations:
pnpm prisma migrate deploy- Push code to GitHub:
git add .
git commit -m "Production deployment"
git push origin main- Connect repository to Vercel:
- Go to vercel.com/new
- Select your GitHub repository
- Configure project settings
- Add environment variables
- Deploy!
# Install Vercel CLI
npm install -g vercel
# Deploy
vercel
# Deploy to production
vercel --prod-
In Vercel dashboard:
- Go to Settings → Domains
- Add your custom domain
- Follow DNS configuration instructions
-
Update NEXT_PUBLIC_API_URL:
- Set in Vercel environment variables
- Example:
https://ajo.example.com/api
- Sign up at sentry.io
- Create a new project
- Add to environment variables:
NEXT_PUBLIC_SENTRY_DSN=<your-sentry-dsn>
- Integrate with code:
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
environment: process.env.NODE_ENV,
});Already configured with Vercel Analytics. Monitor in Vercel dashboard.
- Enable rate limiting:
// Add to API routes
import { rateLimit } from '@/lib/rate-limit';
export async function POST(request) {
const { success } = await rateLimit(request);
if (!success) {
return new Response('Too many requests', { status: 429 });
}
// ... rest of handler
}- Add CORS headers:
const headers = {
'Access-Control-Allow-Origin': process.env.NEXT_PUBLIC_API_URL,
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE',
};- Validate all inputs with Zod or similar
- Use minimum required privileges for DB user
- Enable SSL connections
- Set up regular automated backups
- Enable query logging for auditing
- Have contract audited by professional firm before mainnet
- Use timelock for contract upgrades
- Implement emergency pause mechanism
- Monitor contract events for suspicious activity
- Run smoke tests:
pnpm run test:smoke- Verify endpoints:
curl https://your-domain.com/api/health-
Test payment flows:
- Create test circle
- Make contributions
- Process payouts
-
Verify wallet integration:
- Connect Freighter wallet
- Sign transactions
- Confirm blockchain records
- Smart contract deployed and tested on mainnet
- Database backed up and configured
- All environment variables set in Vercel
- Domain configured and SSL active
- Monitoring and alerting configured
- Error tracking enabled
- Rate limiting implemented
- Input validation on all endpoints
- Security headers configured
- HTTPS enforced
- Privacy policy published
- Terms of service published
- Support email configured
Check metrics regularly:
- Application performance (Vercel Analytics)
- Error rates (Sentry)
- Database performance (Query logs)
- Smart contract events (Stellar Explorer)
- Update dependencies monthly
- Review and rotate secrets quarterly
- Monitor blockchain for contract events
- Review logs for suspicious activity
If needed, upgrade:
- Vercel plan for higher limits
- PostgreSQL instance for more connections
- Add CDN for static assets
- Implement caching strategy
# Test connection
psql $DATABASE_URL -c "SELECT 1"
# Check connection string format
# postgresql://user:password@host:port/database- Verify contract builds locally
- Check XLM balance in deployer account
- Ensure network is accessible
- Review deployment logs for specific errors
- Check build logs in Vercel dashboard
- Verify all environment variables are set
- Ensure Node.js version compatibility
- Clear build cache and retry
- Verify Freighter extension is installed
- Check wallet is on correct network
- Ensure account has XLM for fees
- Verify contract address is correct
If critical issues occur:
- Revert to previous version:
vercel rollback- Check logs for root cause
- Fix issue
- Deploy again:
vercel --prodFor deployment issues:
- Check Stellar documentation
- Review Vercel docs
- Open issue on GitHub
- Contact support team
Last Updated: March 2026