Welcome to the PAPI Simulator Community Template! This initiative enables developers to share, discover, and contribute interactive Polkadot API examples and components. By establishing a standardized template system, we create a collaborative ecosystem where developers can learn from each other and build upon existing work.
- Knowledge Sharing: Enable developers to share their Polkadot-API expertise through interactive examples
- Standardization: Provide consistent templates and patterns for high-quality contributions
- Collaboration: Foster a community-driven approach to expanding the PAPI Simulator
- Learning: Create a rich repository of real-world examples for developers at all levels
All community templates should follow the established ExampleFactory pattern:
import type { Network } from "../types/network";
import { ExampleFactory } from "./factory";
export class YourExampleName extends ExampleFactory {
constructor() {
super({
id: "your-example-id",
name: "Your Example Name",
description: "Brief description of what your example does",
level: "beginner" | "intermediate" | "advanced",
categories: ["relevant", "categories", "here"],
});
}
generateCode(network: Network): string {
return `// Your example code here
${this.getImports(network)}
${this.getClientSetup(network)}
// Your implementation...`;
}
}Examples should be categorized appropriately:
transactions- Transfer operations, transaction buildingbalances- Account balance queries and operationsstorage- Chain state and storage queriesqueries- General blockchain queriesblocks- Block-related operationsevents- Event subscriptions and handlingsubscriptions- Real-time data subscriptionswallets- Wallet integration examplescomponents- React components for UIreact- React-specific implementationscompatibility- Cross-chain or compatibility examples
Choose the appropriate difficulty level:
beginner- Simple operations, single API calls, minimal setupintermediate- Multiple operations, state management, error handlingadvanced- Complex workflows, advanced patterns, performance optimizations
- TypeScript: All examples must be written in TypeScript with proper typing
- Error Handling: Include comprehensive error handling and user feedback
- Documentation: Add clear comments explaining complex operations
- Consistency: Follow the established coding patterns and style
- Responsive Design: Ensure components work on desktop and mobile
- Accessibility: Follow web accessibility standards
- Loading States: Show appropriate loading indicators
- Error States: Provide clear error messages and recovery options
- Multi-Network: Examples should work across all supported networks
- Network-Specific: Handle network-specific configurations properly
- Test Networks: Prioritize testnet usage for safety
Basic operations that demonstrate a single concept:
// Query account balance
// Subscribe to blocks
// Basic transfersFull React components with user interaction:
// Wallet connection interfaces
// Transaction builders
// Real-time dashboardsComplex multi-step operations:
// Multi-signature workflows
// Staking operations
// Governance participationsrc/lib/examples/
โโโ YourExampleName.ts # Main example factory
โโโ components/ # React components (if applicable)
โ โโโ YourComponent.tsx
โโโ utils/ # Utility functions
โ โโโ yourUtils.ts
โโโ __tests__/ # Tests (optional but recommended)
โโโ YourExampleName.test.ts
git clone https://github.com/developerfred/papi-simulator.git
cd papi-simulator
npm install- Create a new file in
src/lib/examples/ - Extend the
ExampleFactoryclass - Implement the
generateCodemethod - Add your example to the registry
Add your example to src/lib/examples/index.ts:
import { YourExampleName } from "./YourExampleName";
exampleRegistry.registerMany([
// ... existing examples
new YourExampleName(),
]);npm run devNavigate to your example in the playground and verify it works correctly.
export class CustomQueryExample extends ExampleFactory {
constructor() {
super({
id: "custom-query",
name: "Custom Chain Query",
description: "Query custom chain state",
level: "beginner",
categories: ["queries", "storage"],
});
}
generateCode(network: Network): string {
return `// Custom chain query example
${this.getImports(network)}
${this.getClientSetup(network)}
const queryChainState = async () => {
try {
// Your query implementation
console.log("Querying chain state...");
} catch (error) {
console.error("Query failed:", error);
}
};
queryChainState();`;
}
}export class InteractiveComponentExample extends ExampleFactory {
constructor() {
super({
id: "interactive-component",
name: "Interactive Component",
description: "React component with user interaction",
level: "intermediate",
categories: ["components", "react", "wallets"],
});
}
generateCode(network: Network): string {
return `// Interactive React component
${this.getImports(network)}
export default function InteractiveComponent() {
const [state, setState] = useState(null);
// Component implementation...
return (
<div style={{ /* styles */ }}>
{/* Component JSX */}
</div>
);
}`;
}
}- Consistency: Follow the existing design patterns and color schemes
- Simplicity: Keep interfaces clean and focused
- Responsiveness: Ensure components work on all screen sizes
- Accessibility: Include proper ARIA labels and keyboard navigation
Use inline styles for consistency with existing examples:
const containerStyle = {
fontFamily: 'system-ui, -apple-system, sans-serif',
maxWidth: '600px',
margin: '0 auto',
backgroundColor: 'var(--surface, #fff)',
color: 'var(--text-primary, #000)',
borderRadius: '12px',
boxShadow: '0 4px 20px rgba(0, 0, 0, 0.08)',
};return (
<div style={containerStyle}>
{/* Header with network branding */}
<div style={headerStyle}>
<h2>Component Title</h2>
<p>Component description</p>
</div>
{/* Main content */}
<div style={contentStyle}>
{/* Your component content */}
</div>
{/* Footer with status/results */}
{result && (
<div style={resultStyle}>
{/* Results display */}
</div>
)}
</div>
);- Never store private keys: Use wallet extensions for signing
- Validate addresses: Always validate recipient addresses
- Test networks first: Encourage testnet usage
- Clear warnings: Display clear warnings for mainnet operations
// Example safety checks
if (!recipient || !amount) {
setError('Please fill in all fields');
return;
}
const numAmount = parseFloat(amount);
if (isNaN(numAmount) || numAmount <= 0) {
throw new Error('Please enter a valid amount');
}// Main component description
export default function ComponentName() {
// State management
const [isLoading, setIsLoading] = useState(false);
// Effect for initialization
useEffect(() => {
// Initialize component
}, []);
// Handler for user actions
const handleSubmit = async () => {
// Implementation with error handling
};
}Provide clear descriptions that explain:
- What the example does
- When to use it
- Key concepts demonstrated
- Prerequisites or setup required
- Works on all supported networks
- Handles loading states properly
- Displays errors clearly
- Responsive design works
- Accessibility features function
- Console output is helpful
- Links to block explorers work
// Example test structure
describe('YourExampleName', () => {
it('should generate valid code', () => {
const example = new YourExampleName();
const code = example.generateCode(mockNetwork);
expect(code).toContain('expected content');
});
});- Fork the repository
- Create a feature branch:
git checkout -b feature/your-example-name - Commit your changes:
git commit -m "Add YourExampleName" - Push to the branch:
git push origin feature/your-example-name - Open a Pull Request
## Description
Brief description of your example and what it demonstrates.
## Type of Change
- [ ] New example
- [ ] Enhancement to existing example
- [ ] Bug fix
- [ ] Documentation update
## Testing
- [ ] Tested on all supported networks
- [ ] Verified responsive design
- [ ] Checked accessibility
- [ ] Manual testing completed
## Screenshots
Include screenshots of your example in action.
## Additional Notes
Any additional information about your contribution.- Automated Checks: Ensure builds pass and no linting errors
- Code Review: Maintainers will review code quality and patterns
- Testing: Verify functionality across networks
- Documentation: Check that documentation is clear and complete
Contributors will be recognized in:
- Repository README
- Example metadata
- Community announcements
Outstanding examples may be:
- Featured in documentation
- Used in tutorials
- Promoted on social media
- Discussions: Use GitHub Discussions for questions
- Issues: Report bugs or request features via GitHub Issues
- Forum: Join the conversation on Polkadot Forum
- Template Marketplace: Browseable collection of community templates
- Example Rating System: Community voting on example quality
- Advanced Search: Filter examples by complexity, use case, etc.
- Integration Examples: Templates for common dApp patterns
- Video Tutorials: Walkthrough videos for complex examples
- Monthly Challenges: Themed example creation contests
- Expert Reviews: Code reviews by ecosystem experts
- Workshop Series: Live coding sessions with community
All community contributions are subject to the same MIT License as the main project.
Thank you to all contributors who help make the PAPI Simulator a valuable resource for the Polkadot developer community!
Ready to contribute? Start by exploring existing examples, then create your own following these guidelines. We can't wait to see what you build! ๐