Skip to main content

dapp-common-skill

Common DApp development patterns and UI components. Use this skill whenever the user wants to build a DApp, create a wallet-connected web app, add token transfers, chain switching, message signing, transaction status tracking, or any blockchain-interactive frontend. Also use when the user mentions DApp layout, transfer forms, signing panels, gas estimation, chain selectors, wallet connection UI, or multi-chain architecture — even if they don't explicitly say "DApp". Use proactively for any web3 frontend work including React + Vite, Next.js, or Vue projects that interact with wallets. Pair with a wallet-specific skill (e.g. Bitget Wallet Developer Skill) for complete DApp development. Do NOT use for smart contract development, backend services, or wallet-internal implementation.

Informations de source

Dépôt
bitget-wallet-ai-lab/bitget-wallet-developer-skill
Dernière activité de la source
24 mars 2026 à 14:50
Langue détectée de SKILL.md
anglais
Étoiles
0
Forks
0

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Explorateur de fichiers
11 fichiers

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
dapp-common-skill
description
Common DApp development patterns and UI components. Use this skill whenever the user wants to build a DApp, create a wallet-connected web app, add token transfers, chain switching, message signing, transaction status tracking, or any blockchain-interactive frontend. Also use when the user mentions DApp layout, transfer forms, signing panels, gas estimation, chain selectors, wallet connection UI, or multi-chain architecture — even if they don't explicitly say "DApp". Use proactively for any web3 frontend work including React + Vite, Next.js, or Vue projects that interact with wallets. Pair with a wallet-specific skill (e.g. Bitget Wallet Developer Skill) for complete DApp development. Do NOT use for smart contract development, backend services, or wallet-internal implementation.
license
MIT
metadata
{"author":"Bitget Wallet","version":"1.0.0","tags":["dapp","frontend","react","web3","ux","transfer","signing","chain-switching"]}
# DApp Common Skill Standard patterns for building production-quality DApp frontends. Multi-chain by design — supports EVM, Solana, Bitcoin, TON, Aptos, Cosmos, Tron, and Sui. ## Instructions ### Step 1: Understand What the User Wants Before writing any code, clarify the DApp's purpose and scope. **Must ask:** | Question | Why | Do NOT assume | |----------|-----|---------------| | What does this DApp do? (swap, transfer, NFT mint, dashboard, etc.) | Determines which modules to load | Never assume "just a connect button" | | **Which chains?** (EVM, Solana, Bitcoin, TON, Aptos, Cosmos, Tron, Sui) | Determines chain adapter(s) to implement | **Never default to EVM-only** | | Single-chain or multi-chain? | If multi-chain, need chain-family tabs | Never assume single-chain | | Framework preference? (React + Vite, Next.js, Vue) | Determines component syntax | Default to React + Vite if not specified | | Need token transfers? If so, native only or token too? | Determines transfer form complexity | Never hardcode amount or skip input | | Need message signing? What types? (login, authorization, typed data) | Determines signing UI | Never skip sign type selector | **Do NOT assume EVM.** If the user says "build a DApp" without specifying chains, you MUST ask which chains they want. If the user specifies a wallet (e.g. "Bitget Wallet"), check which chains that wallet supports and ask the user to choose. **If using Wagmi / RainbowKit / WalletConnect (adapter path), also ask:** | Question | Why | Do NOT assume | |----------|-----|---------------| | Do you have a Reown (WalletConnect) Project ID? | Required for WalletConnect QR / mobile wallet. Not needed for EIP-6963 browser extension only. | Never hardcode `'YOUR_PROJECT_ID'` and move on | If they don't have one, guide them: 1. Go to [dashboard.reown.com](https://dashboard.reown.com/) 2. Sign up / sign in → click **"+ Project"** → select **"AppKit"** → enter project name → **"Create"** 3. Copy the Project ID from the project page 4. Store it in `.env` as `VITE_WALLETCONNECT_PROJECT_ID` (Vite) or `NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID` (Next.js) > **Without a Project ID:** EIP-6963 injected wallet discovery (browser extensions) still works. Only WalletConnect QR code and mobile wallet connections are disabled. ### Step 2: Route to the Right References | User Intent | Load References | |---|---| | "Build a DApp" (generic, EVM) | `layout.md` + `adapter-integration.md` + `ux-patterns.md` + ask what features | | "Build a DApp" (non-EVM or multi-chain) | `layout.md` + `wallet-connection.md` + `ux-patterns.md` + ask what features | | "Use Wagmi / RainbowKit / WalletConnect" | `adapter-integration.md` | | "Add transfer / send tokens" | `transfer.md` + `transaction-lifecycle.md` + `gas-and-fees.md` | | "Add ERC-20 token transfer" | `transfer.md` + `token-approval.md` + `gas-and-fees.md` | | "Add chain switching / multi-chain" | `chain-switching.md` | | "Add message signing / SIWE / login" | `signing.md` | | "Show transaction status / history" | `transaction-lifecycle.md` + `ux-patterns.md` (toast) | | "Show gas fees / fee estimate" | `gas-and-fees.md` | | "Full-featured DApp" | All references | > **Always load `ux-patterns.md`** for any DApp — it covers loading states, toasts, empty states, and confirmation dialogs that every DApp needs. ### Connection Architecture Decision A production DApp should let users **choose their connection method** (browser extension, WalletConnect QR, mobile deep link, etc.), not hardcode a single method. The "Connect Wallet" button should open a modal showing all available options. **Recommended approach by framework:** ``` React + EVM (any) → adapter-integration.md (RainbowKit — connection modal built-in) Vue / Angular / Vanilla JS → adapter-integration.md (Web3Modal — framework-agnostic modal) Non-EVM chains (SOL/BTC/TON) → wallet-connection.md (direct provider, no adapter ecosystem yet) Multi-chain (EVM + non-EVM) → adapter-integration.md (EVM) + wallet-connection.md (non-EVM) ``` > **Default recommendation: Use RainbowKit or Web3Modal.** They provide a connection modal that auto-detects installed wallets (EIP-6963), shows WalletConnect QR code for mobile, and lets the user choose. Do NOT build a single-method "Connect Bitget Wallet" button for production EVM DApps — always offer multiple connection paths. **Connection methods the modal should support:** | Method | How It Works | When Available | |--------|-------------|----------------| | **Browser Extension** (EIP-6963) | Auto-detects installed wallets, user clicks one | Wallet extension installed | | **WalletConnect QR** | Scan QR code with mobile wallet | Always (needs Project ID) | | **Deep Link** | Opens mobile wallet app directly | Mobile browser | | **Email / Social** | Embedded wallet via Reown AppKit | If configured | When using adapters, Wagmi hooks replace the custom hooks from `wallet-connection.md`. But the UI components (TransferForm, SigningPanel, TxStatus, etc.) remain the same — they are adapter-agnostic. ### Step 3: Apply Standard DApp Architecture Every DApp MUST follow this structure. Non-negotiable. **Adapter-based DApp (Wagmi/RainbowKit — recommended for React + EVM):** ``` src/ ├── config/ │ └── wagmi.ts # Wagmi config + chains + connectors + wallet list ├── components/ │ ├── TransferForm.tsx # Same as below — adapter-agnostic │ ├── SigningPanel.tsx # Same as below — adapter-agnostic │ ├── TxStatus.tsx # Transaction lifecycle display │ └── Layout.tsx # Use <ConnectButton /> from RainbowKit ├── utils/ │ ├── format.ts # Address shortening, amount formatting │ ├── chains.ts # Chain configs │ └── errors.ts # User-friendly error messages ├── App.tsx # WagmiProvider + RainbowKitProvider └── main.tsx ``` **Single-chain DApp (direct provider):** ``` src/ ├── components/ │ ├── WalletStatus.tsx # Header: address + chain + balance │ ├── TransferForm.tsx # Amount + recipient + token + send │ ├── SigningPanel.tsx # Message input + type selector + sign │ ├── TxStatus.tsx # Transaction lifecycle display │ └── Layout.tsx # Page shell with header + content ├── hooks/ │ ├── useWalletConnection.ts # Connect / disconnect / account state │ ├── useTransfer.ts # Build + send + track transaction │ ├── useSigning.ts # Sign messages + verify │ └── useBalance.ts # Native + token balance queries ├── utils/ │ ├── format.ts # Address shortening, amount formatting │ ├── chains.ts # Chain configs (name, RPC, explorer, icon) │ └── errors.ts # User-friendly error messages ├── App.tsx # Router + providers └── main.tsx # Entry point ``` **Multi-chain DApp (2+ chain families):** ``` src/ ├── chains/ # ← Chain adapter layer │ ├── types.ts # ChainAdapter interface │ ├── evm.ts # EVM adapter (ethers.js) │ ├── solana.ts # Solana adapter (@solana/web3.js) │ ├── bitcoin.ts # Bitcoin adapter (UniSat API) │ ├── ton.ts # TON adapter (TonConnect) │ └── index.ts # Registry: chain → adapter mapping ├── components/ │ ├── WalletStatus.tsx # Header: address + chain + balance │ ├── ChainFamilySelector.tsx # EVM / Solana / Bitcoin / TON tabs │ ├── ChainSelector.tsx # Sub-chain selector (within EVM) │ ├── TransferForm.tsx # Uses active chain adapter │ ├── SigningPanel.tsx # Adapts sign types per chain │ ├── TxStatus.tsx # Transaction lifecycle display │ └── Layout.tsx # Page shell with header + content ├── hooks/ │ ├── useWalletConnection.ts # Multi-chain connect / disconnect │ ├── useActiveChain.ts # Current chain family + sub-chain │ ├── useTransfer.ts # Delegates to chain adapter │ ├── useSigning.ts # Delegates to chain adapter │ └── useBalance.ts # Delegates to chain adapter ├── utils/ │ ├── format.ts # Address shortening, amount formatting │ ├── chains.ts # All chain configs (EVM + non-EVM) │ └── errors.ts # User-friendly error messages ├── App.tsx └── main.tsx ``` ### Step 4: Follow DApp UX Rules These rules apply to ALL DApps regardless of wallet or chain. Non-negotiable. **Inputs & Data:** 1. **Never hardcode transaction parameters** — always provide input fields for amounts, recipients, and tokens. 2. **Always show chain context** — display which chain the user is on, and provide a way to switch. 3. **Always format amounts for humans** — show ETH not wei, SOL not lamports, with proper decimal places. 4. **Accept ENS names in address fields** (EVM) — resolve `.eth` names and show the resolved address. 5. **Validate addresses per chain** — use chain-specific regex, don't accept invalid formats. **Transaction Lifecycle:** 6. **Always show transaction status** — use a state machine: idle → signing → pending → confirmed/failed. 7. **Always link to explorer** — after any on-chain action, show a clickable link to the block explorer. 8. **Show gas fee estimate before confirmation** — never surprise users with costs. Show Slow/Standard/Fast tiers for EVM. 9. **Show pre-wallet confirmation dialog** — preview the action in the DApp BEFORE triggering the wallet popup. 10. **Use toast notifications** — persistent toasts for tx lifecycle so users see status even after navigating away. **Token Approvals (ERC-20):** 11. **Show approval step explicitly** — "Step 1: Approve" → "Step 2: Transfer" with clear labeling. 12. **Default to exact-amount approvals** — never infinite unless user explicitly opts in. 13. **Check existing allowance** — don't force unnecessary approvals. **Error Handling & Security:** 14. **Always handle errors with user-friendly messages** — map error codes to plain language. 15. **Show what users are signing** — display message content before asking for signature; never sign opaque data. 16. **Separate signing from broadcasting** — provide options for sign-only operations. **Navigation & State:** 17. **Always provide cancel/back paths** — users should never be stuck. 18. **Always persist wallet connection** — reconnect on page reload. 19. **Support both mainnet and testnet** — with a clear visual indicator of which environment. **Visual Polish:** 20. **Use skeleton loading** — show shimmering placeholders while data loads, never blank screens. 21. **Show empty states with CTAs** — "No transactions yet" with actionable guidance, not blank space. 22. **Provide copy buttons** — on addresses, signatures, and transaction hashes. 23. **Support dark mode** — respect system preference via CSS custom properties. ### Step 5: Implement Features Load the relevant reference files and follow the patterns. Every reference includes: - TypeScript types - React hook implementation - Component template - Error handling - Usage example ## Core Knowledge (No Reference Loading Required) ### Amount Formatting ```typescript function formatAmount(raw: string | bigint, decimals: number = 18): string { const value = typeof raw === 'string' ? BigInt(raw) : raw; const divisor = BigInt(10 ** decimals); const whole = value / divisor; const fraction = value % divisor; const fractionStr = fraction.toString().padStart(decimals, '0').slice(0, 6); return `${whole}.${fractionStr}`.replace(/\.?0+$/, '') || '0'; } function parseAmount(display: string, decimals: number = 18): bigint { const [whole = '0', frac = ''] = display.split('.'); const padded = frac.padEnd(decimals, '0').slice(0, decimals); return BigInt(whole + padded); } ``` ### Address Display ```typescript function shortenAddress(address: string, chars: number = 4): string { if (!address) return ''; return `${address.slice(0, chars + 2)}...${address.slice(-chars)}`; } ``` ### Chain Configs ```typescript type ChainFamily = 'evm' | 'solana' | 'bitcoin' | 'ton' | 'aptos' | 'cosmos' | 'tron' | 'sui'; interface ChainConfig { id: string; // unique key: "ethereum", "solana-mainnet", "bitcoin" family: ChainFamily; chainId?: number; // EVM only name: string; symbol: string; decimals: number; rpcUrl: string; explorerUrl: string; explorerTxPath: string; // "/tx/" for EVM, "/transaction/" for Solana, etc. explorerName: string; isTestnet: boolean; } const CHAINS: Record<string, ChainConfig> = { // EVM 'ethereum': { id: 'ethereum', family: 'evm', chainId: 1, name: 'Ethereum', symbol: 'ETH', decimals: 18, rpcUrl: 'https://eth.llamarpc.com', explorerUrl: 'https://etherscan.io', explorerTxPath: '/tx/', explorerName: 'Etherscan', isTestnet: false }, 'bsc': { id: 'bsc', family: 'evm', chainId: 56, name: 'BNB Chain', symbol: 'BNB', decimals: 18, rpcUrl: 'https://bsc-dataseed1.binance.org', explorerUrl: 'https://bscscan.com', explorerTxPath: '/tx/', explorerName: 'BscScan', isTestnet: false }, 'polygon': { id: 'polygon', family: 'evm', chainId: 137, name: 'Polygon', symbol: 'POL', decimals: 18, rpcUrl: 'https://polygon-rpc.com', explorerUrl: 'https://polygonscan.com', explorerTxPath: '/tx/', explorerName: 'PolygonScan', isTestnet: false }, 'arbitrum': { id: 'arbitrum', family: 'evm', chainId: 42161, name: 'Arbitrum', symbol: 'ETH', decimals: 18, rpcUrl: 'https://arb1.arbitrum.io/rpc', explorerUrl: 'https://arbiscan.io', explorerTxPath: '/tx/', explorerName: 'Arbiscan', isTestnet: false }, 'base': { id: 'base', family: 'evm', chainId: 8453, name: 'Base', symbol: 'ETH', decimals: 18, rpcUrl: 'https://mainnet.base.org', explorerUrl: 'https://basescan.org', explorerTxPath: '/tx/', explorerName: 'BaseScan', isTestnet: false }, 'sepolia': { id: 'sepolia', family: 'evm', chainId: 11155111, name: 'Sepolia', symbol: 'ETH', decimals: 18, rpcUrl: 'https://rpc.sepolia.org', explorerUrl: 'https://sepolia.etherscan.io', explorerTxPath: '/tx/', explorerName: 'Etherscan (Sepolia)', isTestnet: true }, // Solana
Voir sur GitHub
Ce SKILL.md est tres volumineux, SkillsMP affiche donc ici seulement la premiere section. Voir sur GitHub