Creating Mini-Apps
Learn how to build interactive Web3 mini-apps using the Sherry SDK. This guide covers everything from basic concepts to advanced implementations, helping you create engaging social media experiences that seamlessly integrate blockchain functionality.
Understanding Mini-Apps
Mini-apps are interactive widgets that embed directly into social media posts, allowing users to perform Web3 actions without leaving their social feed. They consist of metadata that defines the app structure and actions that users can execute.
Core Components
Every mini-app has three essential parts:
- Metadata: Defines the app's appearance, description, and available actions
- Actions: Interactive elements users can execute (transfers, smart contracts, APIs)
- Parameters: User inputs required to complete actions (amounts, addresses, choices)
The Metadata Interface
The Metadata
object is the foundation of every mini-app. It defines how your app appears to users and what actions they can perform.
interface Metadata {
url: string; // Unique identifier URL for your app
icon: string; // Public URL to your app icon
title: string; // Display name shown to users
description: string; // Brief explanation of functionality
baseUrl?: string; // API server URL (optional, auto-detected)
actions: Action[]; // Array of interactive actions
}
Property Details
url
- Your app's unique identifier
- Must be a URL you control (e.g.,
https://myapp.com/tip-jar
) - Used for app discovery and verification
- Should be stable and permanent
icon
- Visual representation of your app
- Public URL to an image file (PNG, SVG, or JPG)
- Recommended size: 200x200 pixels
- Should be accessible without authentication
title
- User-facing app name
- Keep it concise (2-5 words)
- Clearly describes the app's purpose
- Shown prominently in the UI
description
- Explains what your app does
- One sentence describing the main functionality
- Helps users understand the value proposition
- Keep under 100 characters for best display
baseUrl
- Your API server location (optional)
- Auto-detected from the request in most cases
- Override when using custom domains or proxies
- Must be publicly accessible for the app to work
actions
- Interactive elements users can execute
- Array of different action types
- At least one action is required
- Each action represents a button/interaction
Quick Start Examples
Example 1: Simple Tip Jar
A basic mini-app that allows users to send tips with predefined amounts:
import { createMetadata, Metadata } from '@sherrylinks/sdk';
const tipJarApp: Metadata = {
url: 'https://myapp.com/tip-jar',
icon: 'https://myapp.com/icons/tip.png',
title: 'Creator Tip Jar',
description: 'Support your favorite content creator',
actions: [
{
type: 'transfer',
label: 'Send Tip',
chains: { source: 43114 }, // Avalanche mainnet
to: '0x742d35Cc6734C0532925a3b8D4ccd306f6F4B26C',
amountConfig: {
type: 'radio',
label: 'Tip Amount',
options: [
{ label: 'Coffee', value: 0.01, description: '0.01 AVAX' },
{ label: 'Lunch', value: 0.05, description: '0.05 AVAX' },
{ label: 'Dinner', value: 0.1, description: '0.1 AVAX' },
],
},
},
],
};
export default createMetadata(tipJarApp);
Example 2: NFT Minting
A mini-app that allows users to mint NFTs with custom parameters:
const nftMintApp: Metadata = {
url: 'https://mynft.com/mint',
icon: 'https://mynft.com/icon.png',
title: 'Mint Cosmic NFT',
description: 'Mint your unique cosmic NFT collection',
actions: [
{
type: 'blockchain',
label: 'Mint NFT',
address: '0xNFTContractAddress',
abi: nftContractAbi,
functionName: 'mint',
chains: { source: 43114 },
amount: 0.1, // Mint cost in AVAX
params: [
{
name: 'to',
label: 'Recipient Address',
type: 'address',
required: true,
description: 'Address that will receive the NFT',
},
{
name: 'rarity',
label: 'NFT Rarity',
type: 'select',
required: true,
options: [
{ label: 'Common', value: 1 },
{ label: 'Rare', value: 2 },
{ label: 'Epic', value: 3 },
{ label: 'Legendary', value: 4 },
],
},
],
},
],
};
Example 3: Email Collection + Token Reward
A multi-action app that collects emails and rewards users with tokens:
const emailRewardApp: Metadata = {
url: 'https://newsletter.com/signup',
icon: 'https://newsletter.com/icon.png',
title: 'Newsletter Signup',
description: 'Join our newsletter and get reward tokens',
actions: [
{
type: 'http',
label: 'Join Newsletter',
path: 'https://api.newsletter.com/signup',
params: [
{
name: 'email',
label: 'Email Address',
type: 'email',
required: true,
description: 'Your email for newsletter updates',
},
{
name: 'interests',
label: 'Your Interests',
type: 'select',
required: false,
options: [
{ label: 'DeFi Updates', value: 'defi' },
{ label: 'NFT News', value: 'nft' },
{ label: 'Gaming', value: 'gaming' },
],
},
],
},
{
type: 'blockchain',
label: 'Claim Reward Tokens',
address: '0xRewardTokenContract',
abi: tokenAbi,
functionName: 'claimReward',
chains: { source: 43114 },
params: [
{
name: 'recipient',
label: 'Your Wallet',
type: 'address',
required: true,
},
],
},
],
};
Validation & Error Handling
The Sherry SDK provides robust validation to ensure your mini-apps work correctly. Always validate your metadata before deployment.
Using createMetadata()
The recommended approach for validation:
import { createMetadata } from '@sherrylinks/sdk';
try {
const validatedMetadata = createMetadata(tipJarApp);
console.log('Mini-app validated successfully!');
// Use validated metadata for your app
return validatedMetadata;
} catch (error) {
console.error('Validation failed:', error.message);
// Handle validation errors
}
Using validateMetadata()
For more detailed validation information:
import { validateMetadata } from '@sherrylinks/sdk';
const validationResult = validateMetadata(tipJarApp);
if (validationResult.isValid) {
console.log('Metadata is valid:', validationResult.data);
} else {
console.error('Validation errors:', validationResult.errors);
// Handle specific validation issues
validationResult.errors.forEach(error => {
console.log(`Field: ${error.field}, Issue: ${error.message}`);
});
}
Common Validation Errors
Missing Required Fields
// ❌ Missing required 'actions' field
const invalidMetadata = {
url: 'https://myapp.com',
title: 'My App',
description: 'Description',
// actions: [] // Missing!
};
Invalid URLs
// ❌ Invalid URL format
const invalidMetadata = {
url: 'not-a-valid-url', // Must be a valid URL
icon: 'also-invalid', // Must be a valid URL
// ...
};
Invalid Action Configuration
// ❌ Invalid action type
const invalidAction = {
type: 'invalid-type', // Must be 'transfer', 'blockchain', 'http', etc.
label: 'Do Something',
};
Action Types Overview
The Sherry SDK supports several action types, each designed for specific use cases:
Transfer Actions
Perfect for simple token transfers with built-in UI components:
{
type: 'transfer',
label: 'Send Payment',
chains: { source: 43114 },
to: '0x...', // Fixed recipient
amount: 0.1 // Fixed amount
}
When to use: Tips, donations, simple payments, fixed-amount transfers
Blockchain Actions
For smart contract interactions with custom ABIs:
{
type: 'blockchain',
label: 'Mint NFT',
address: '0xContractAddress',
abi: contractAbi,
functionName: 'mint',
chains: { source: 43114 },
params: [/* custom parameters */]
}
When to use: NFT minting, token swaps, DAO voting, DeFi operations
HTTP Actions
For data collection and external API integration:
{
type: 'http',
label: 'Submit Form',
path: 'https://api.myapp.com/submit',
params: [/* form parameters */]
}
When to use: Email collection, surveys, data submission, external integrations
Dynamic Actions
For server-side computed actions with complex business logic:
{
type: 'dynamic',
label: 'Smart Execute',
path: '/api/compute',
chains: { source: 43114 },
params: [/* input parameters */]
}
When to use: Complex calculations, real-time pricing, conditional logic
Best Practices
Metadata Design
- Clear Titles: Use descriptive, action-oriented titles
- Helpful Descriptions: Explain value proposition in one sentence
- Professional Icons: Use high-quality, recognizable icons
- Stable URLs: Use URLs you control and won't change
User Experience
- Minimal Friction: Reduce the number of required inputs
- Clear Labels: Use user-friendly parameter labels
- Helpful Descriptions: Add context for complex parameters
- Error Handling: Provide clear error messages
Security Considerations
- Validate Inputs: Always validate user inputs server-side
- Rate Limiting: Implement rate limiting on your APIs
- CORS Headers: Configure proper CORS for cross-origin requests
- Input Sanitization: Sanitize all user inputs before processing
Performance Optimization
- Small Icons: Optimize icon file sizes for fast loading
- Minimal Parameters: Only ask for essential information
- Fast APIs: Ensure your backend responds quickly
- Caching: Cache static content where possible
Testing Your Mini-App
Local Development
- Create your metadata object
- Validate using
createMetadata()
- Test with the Sherry debugger
- Deploy to a public URL for testing
Production Deployment
- Deploy your API to a reliable hosting provider
- Ensure CORS headers are properly configured
- Test all user flows thoroughly
- Monitor performance and error rates
Next Steps
Now that you understand the basics, explore specific action types:
- Transfer Actions - Simple token transfers
- Blockchain Actions - Smart contract interactions
- Dynamic Actions - Server-side logic
- Action Parameters - User input configuration
- Complete Tutorial - End-to-end implementation guide