ICP App Generator
Overview
This skill enables comprehensive Internet Computer Protocol (ICP) application development from initial scaffolding through production deployment. It supports multiple backend languages (Motoko, Rust, Azle), provides pre-built templates for common patterns, and enforces ICP best practices for security, performance, and scalability.
Core Capabilities
1. Project Scaffolding
Generate new ICP projects with proper structure:
- Basic web app: Simple frontend + backend canister
- Full-stack dapp: Frontend + multiple backend canisters
- DeFi protocol: Token canisters + trading logic + frontend
- NFT marketplace: NFT canister + marketplace + minting
- DAO: Governance + treasury + voting mechanisms
- Social dapp: User profiles + content + interactions
2. Canister Development
Create canisters in your preferred language:
- Motoko: Native ICP language with built-in actor model
- Rust: Systems programming with ICP CDK
- Azle: TypeScript/JavaScript with familiar syntax
3. Frontend Integration
- React/Vue/Svelte templates with agent-js
- Internet Identity authentication
- Canister interaction hooks
- Type-safe interfaces from Candid
4. Token Standards
- ICRC-1: Fungible token standard
- ICRC-2: Approve/transferFrom extension
- ICRC-7: NFT standard
- Custom token implementations
5. Testing & Quality
- Unit tests for canisters
- Integration tests with PocketIC
- End-to-end tests for full dapps
6. Deployment
- Local development with
dfx start - Mainnet deployment with environment switching
- CI/CD pipeline generation
- Canister monitoring setup
Quick Start Workflow
Step 1: Initialize Project
# Generate new project from template
dfx new my-project --type <template>
# Or use the scaffold script
python3 scripts/scaffold.py my-project --template <type> --language <lang>
Step 2: Develop Canisters
Choose language and implement:
- Motoko: See MOTOKO_GUIDE.md
- Rust: See RUST_GUIDE.md
- Azle: See AZLE_GUIDE.md
Step 3: Add Frontend (Optional)
# Generate frontend template
python3 scripts/add-frontend.py --framework react
# Integrate Internet Identity
python3 scripts/add-auth.py --provider internet-identity
Step 4: Test Locally
# Start local replica
dfx start --background
# Deploy locally
dfx deploy
# Run tests
python3 scripts/test.py --all
Step 5: Deploy to Mainnet
# Configure for mainnet
python3 scripts/configure-deployment.py --network ic
# Deploy
dfx deploy --network ic
Project Structure
my-project/
├── dfx.json # Canister configuration
├── README.md # Project documentation
├── src/
│ ├── backend/ # Backend canisters
│ │ ├── main.mo # (Motoko) or main.rs (Rust) or index.ts (Azle)
│ │ └── types.mo # Type definitions
│ └── frontend/ # Frontend application
│ ├── src/
│ │ ├── App.tsx # Main app component
│ │ └── declarations/ # Auto-generated Candid bindings
│ └── package.json
├── tests/ # Test suites
│ ├── unit/
│ └── integration/
└── .github/ # CI/CD workflows
└── workflows/
└── deploy.yml
Configuration Files
dfx.json
Main configuration defining canisters, networks, and defaults:
{
"canisters": {
"backend": {
"type": "motoko",
"main": "src/backend/main.mo"
},
"frontend": {
"type": "assets",
"source": ["src/frontend/dist"]
}
},
"networks": {
"local": {
"bind": "127.0.0.1:4943"
},
"ic": {
"providers": ["https://ic0.app"]
}
}
}
Environment Switching
Use scripts/configure-deployment.py to switch between local and mainnet:
- Automatically updates
dfx.json - Manages identity selection
- Handles cycle wallet configuration
Resources
Scripts (scripts/)
Executable utilities for common operations:
- scaffold.py: Generate new project from templates
- add-canister.py: Add new canister to existing project
- add-frontend.py: Generate frontend boilerplate
- add-auth.py: Integrate authentication (Internet Identity)
- add-token.py: Add ICRC token canister
- configure-deployment.py: Switch deployment environments
- test.py: Run test suites
- deploy.py: Deploy with validation
References (references/)
Documentation for informed development:
- BEST_PRACTICES.md: Security patterns, performance tips, anti-patterns
- MOTOKO_GUIDE.md: Language specifics, patterns, examples
- RUST_GUIDE.md: Rust CDK usage, patterns, examples
- AZLE_GUIDE.md: TypeScript SDK usage, patterns
- FRONTEND_INTEGRATION.md: agent-js usage, Candid bindings
- ICRC_TOKENS.md: Token standards implementation
- INTERNET_IDENTITY.md: Authentication integration
- CANISTER_PATTERNS.md: Common design patterns
- TESTING_GUIDE.md: Testing strategies and tools
- DEPLOYMENT.md: Production deployment guide
Assets (assets/)
Templates and boilerplate:
- templates/basic/: Minimal web app template
- templates/fullstack/: Frontend + backend template
- templates/defi/: DeFi protocol template
- templates/nft-marketplace/: NFT marketplace template
- templates/dao/: DAO governance template
- templates/social/: Social dapp template
- snippets/: Code snippets for common patterns
- workflows/: GitHub Actions templates
Language Selection Guide
Choose Motoko when:
- Building native ICP applications
- Want built-in Candid support
- Need automatic memory management
- Prefer functional programming style
Choose Rust when:
- Need fine-grained control
- Performance is critical
- Have existing Rust expertise
- Need complex data structures
Choose Azle when:
- Prefer TypeScript/JavaScript
- Have web development background
- Want familiar syntax
- Need rapid prototyping
Security Checklist
Before mainnet deployment:
- Review access control on all public methods
- Validate all inputs and sanitize data
- Check for reentrancy vulnerabilities
- Implement rate limiting where needed
- Secure cycle management
- Review upgrade compatibility
- Test thoroughly on local replica
- Audit critical canisters
Common Patterns
Access Control
import Principal "mo:base/Principal";
actor {
let owner = Principal.fromText("...");
public shared(msg) func adminOnly() : async Text {
if (msg.caller != owner) {
throw Error.reject("Unauthorized");
};
"Success"
};
};
State Management
import HashMap "mo:base/HashMap";
import Iter "mo:base/Iter";
stable var entries : [(Text, Nat)] = [];
let map = HashMap.HashMap<Text, Nat>(10, Text.equal, Text.hash);
system func preupgrade() {
entries := Iter.toArray(map.entries());
};
system func postupgrade() {
for ((key, value) in entries.vals()) {
map.put(key, value);
};
entries := [];
};
Inter-Canister Calls
import IC "ic:aaaaa-aa";
actor {
public func callOtherCanister(canisterId : Principal) : async Text {
let result = await IC.canister.canister_id {
public query func greet() : async Text;
}.greet();
result
};
};
Getting Help
- ICP Documentation: https://internetcomputer.org/docs
- Developer Forum: https://forum.dfinity.org
- ICP SDK Issues: https://github.com/dfinity/sdk
- Motoko Issues: https://github.com/dfinity/motoko