A complete decentralized application built on Sui that allows users to send tips directly to a tip jar owner. The application features gas-free transactions through Enoki sponsorship and a clean, user-friendly interface.
tip_jar/
βββ tip_jar_contract/ # Move smart contract
β βββ Move.toml # Contract configuration
β βββ sources/
β β βββ tip_jar_contract.move # Main contract implementation
β βββ tests/
β βββ tip_jar_contract_tests.move # Comprehensive test suite
βββ tip_jar_dapp/ # Next.js frontend
βββ package.json # Dependencies and scripts
βββ src/
β βββ app/
β β βββ api/sponsor-transaction/ # Enoki API route
β β βββ layout.tsx # App layout with providers
β β βββ page.tsx # Main page
β βββ components/
β β βββ SuiProvider.tsx # Sui network provider
β β βββ WalletConnection.tsx # Wallet connection component
β β βββ TipJar.tsx # Main tip jar component
β βββ hooks/
β βββ useSponsoredTransaction.ts # Transaction hook
βββ .env.example # Environment variables template
βββ .env.local # Local environment configuration
- Direct Transfers: Tips are transferred directly to the owner's address
- Statistics Tracking: Tracks total tips received and tip count
- Event Emission: Emits events for frontend integration
- Comprehensive Testing: 9 test cases covering all functionality
- Security: Input validation and error handling
- Wallet Integration: Seamless connection with Sui wallets
- Real-time Statistics: Live updates of tip jar statistics
- Gas-free Transactions: Enoki-sponsored transactions (API implemented)
- Responsive Design: Clean, mobile-friendly interface
- Error Handling: Comprehensive error handling and user feedback
The tip jar contract implements a simple but robust tipping system:
/// Send a tip to the tip jar owner
/// The tip is immediately transferred to the owner
/// Only statistics are updated in the shared object
public entry fun send_tip(
tip_jar: &mut TipJar,
payment: Coin<SUI>,
ctx: &mut TxContext,
) {
let tip_amount = coin::value(&payment);
assert!(tip_amount > 0, EInvalidTipAmount);
// Transfer payment directly to the tip jar owner
transfer::public_transfer(payment, tip_jar.owner);
// Update statistics
tip_jar.total_tips_received = tip_jar.total_tips_received + tip_amount;
tip_jar.tip_count = tip_jar.tip_count + 1;
// Emit event for frontend tracking
event::emit(TipSent { /* ... */ });
}- Direct Transfers: Tips go directly to the owner, no withdrawal needed
- Shared Object: The TipJar object is shared for concurrent access
- Event-Driven: Events enable real-time frontend updates
- Minimal Storage: Only statistics are stored on-chain
Comprehensive test suite with 9 test cases:
- Contract initialization
- Basic tip functionality
- Multiple tips from different users
- Multiple tips from same user
- Zero tip validation
- Event emission
- Getter function validation
- Large tip amounts
- Minimal tip amounts (1 MIST)
Run tests with:
cd tip_jar_contract
sui move test- Next.js 15: Latest React framework with App Router
- TypeScript: Full type safety
- Tailwind CSS: Utility-first styling
- Sui TypeScript SDK: Blockchain interaction
- Sui dApp Kit: Wallet integration
- Enoki: Sponsored transactions
Sets up the Sui network configuration and wallet providers:
const { networkConfig } = createNetworkConfig({
testnet: { url: getFullnodeUrl('testnet') },
});Handles wallet connection with clean UI using Sui's ConnectButton component.
Main application interface featuring:
- Live statistics display
- Tip amount input with validation
- Gas-free transaction indication
- Success/error feedback
- Responsive design
Enoki integration provides gas-free transactions:
-
Backend API (
/api/sponsor-transaction):- Creates sponsored transactions
- Executes signed transactions
- Error handling and validation
-
Frontend Hook (
useSponsoredTransaction):- Abstracts transaction sponsorship
- Provides loading states
- Success/error callbacks
- Node.js 18+
- Sui CLI - Installation Guide
- Git
- Testnet SUI tokens - Get from Faucet
- Clone and navigate to contract:
cd tip_jar_contract- Test the contract:
sui move test- Deploy to testnet:
sui client publish --gas-budget 20000000- Note the Package ID and TipJar object ID for frontend configuration
- Navigate to frontend:
cd tip_jar_dapp- Install dependencies:
npm install- Configure environment:
cp .env.example .env.local- Update
.env.localwith your values:
NEXT_PUBLIC_PACKAGE_ID=your_package_id_here
NEXT_PUBLIC_TIP_JAR_ID=your_tip_jar_object_id_here
ENOKI_SECRET_KEY=your_enoki_secret_key_here- Start development server:
npm run devNEXT_PUBLIC_PACKAGE_ID: Deployed contract package IDNEXT_PUBLIC_TIP_JAR_ID: TipJar shared object IDENOKI_SECRET_KEY: Enoki API secret keyNEXT_PUBLIC_ENOKI_API_URL: Enoki API endpoint
The application is configured for Sui testnet by default. To use mainnet:
- Update
SuiProvider.tsxnetwork configuration - Update environment variables for mainnet contract addresses
- Ensure Enoki is configured for mainnet
cd tip_jar_contract
sui move testAll tests pass and cover:
- β Contract initialization
- β Basic tipping functionality
- β Multiple user interactions
- β Input validation
- β Event emission
- β Statistical accuracy
- β Edge cases
The frontend includes TypeScript compilation checks:
cd tip_jar_dapp
npm run build- Compile and deploy:
sui client publish --gas-budget 20000000- Save important addresses:
- Package ID
- TipJar object ID
- Owner address
Deploy on Vercel, Netlify, or similar platforms:
- Build for production:
npm run build-
Configure environment variables on your deployment platform
-
Deploy using your platform's deployment process
- Deploy the contract to get your unique tip jar
- Share your tip jar address with supporters
- Tips are automatically transferred to your wallet
- Monitor statistics through the frontend
- Visit the tip jar web interface
- Connect your Sui wallet
- Enter tip amount in SUI
- Send tip (gas-free via Enoki)
- Receive confirmation of successful tip
- Input validation (non-zero tips)
- Direct transfers (no custody risk)
- Minimal storage footprint
- Comprehensive error handling
- Environment variable protection
- Input sanitization
- Error boundaries
- Secure API routes
- Error Handling: Additional user-friendly error messages could be added
- Testing: Frontend unit tests could be added
- Mobile Optimization: Further mobile UX improvements
- Coin Selection: Could be optimized for better coin selection strategy
- Multi-Currency Support: Accept different token types
- Tip Messages: Allow tippers to leave messages
- Analytics Dashboard: Extended statistics and charts
- Social Features: Leaderboards, social sharing
- Recurring Tips: Subscription-based tipping
This is an educational project for learning Sui development. Contributions welcome:
- Fork the repository
- Create feature branch
- Make changes with tests
- Submit pull request
MIT License - feel free to use this code for learning and building your own projects.
This project demonstrates:
- β One-time witness pattern
- β Shared objects
- β Direct transfers
- β Event emission
- β Entry functions
- β Comprehensive testing
- β Wallet connectivity
- β Transaction building
- β Real-time data fetching
- β User experience design
- β Error handling
- β Direct payment flows
- β Statistics tracking
- β Gas sponsorship
- β Event-driven updates
Built with β€οΈ on Sui β’ Powered by Enoki for gas-free transactions