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.

Informações da origem

Repositório
bitget-wallet-ai-lab/bitget-wallet-developer-skill
Última atividade na origem
24 de março de 2026 às 14:50
Idioma detectado do SKILL.md
inglês
Estrelas
0
Forks
0

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Explorador de arquivos
11 arquivos

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
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
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub