migrating-an-onchainkit-app
OnchainKit Migration Skill
Migrate apps from @coinbase/onchainkit to standalone wagmi/viem components with zero OnchainKit dependency.
Before Starting
Create a mistakes.md file in the project root:
# Migration Mistakes & Learnings
Track errors, fixes, and lessons learned during OnchainKit migration.
## Errors
## Lessons Learned
Append every error, fix, and lesson to this file throughout the migration. This file improves the skill over time.
Migration Workflow
Migrations MUST happen in this order. Do not skip steps.
Step 1: Detection
Scan the project to understand current OnchainKit usage:
- Search all files for
@coinbase/onchainkitimports - Identify which components are used:
- Provider:
OnchainKitProvider(always present if using OnchainKit) - Wallet:
Wallet,ConnectWallet,WalletDropdown,WalletModal,Connected - Transaction:
Transaction,TransactionButton,TransactionStatus - Other:
Identity,Avatar,Name,Address,Swap,Checkout, etc.
- Provider:
- Check
package.jsonfor existingwagmi,viem,@tanstack/react-querydependencies - Identify the project's styling approach (Tailwind, CSS Modules, styled-components, etc.)
- Report findings to the user before proceeding
Step 2: Provider Migration (always first)
Read references/provider-migration.md for detailed instructions and code.
Summary:
- Ensure
wagmi,viem, and@tanstack/react-queryare installed - Create
wagmi-config.tswith chain and connector configuration - Replace
OnchainKitProviderwithWagmiProvider+QueryClientProvider - Remove
@coinbase/onchainkit/styles.cssimport - Remove any
SafeAreaor MiniKit imports from layout files
Validation gate: Run npm run build (or the project's build command). Must pass before continuing. If it fails, fix errors and document them in mistakes.md.
Step 3: Wallet Migration (after provider)
Read references/wallet-migration.md for detailed instructions and code.
Summary:
- Create a
WalletConnectcomponent using wagmi hooks (useAccount,useConnect,useDisconnect) - Component includes a modal with wallet options: Base Account, Coinbase Wallet, MetaMask
- Shows truncated address + disconnect button when connected
- Replace all OnchainKit wallet imports and component usage
Validation gate: Run npm run build. Must pass before continuing. Document any errors in mistakes.md.
Step 4: Transaction Migration (after wallet)
Read references/transaction-migration.md for detailed instructions and code.
Summary:
- Check the
chainIdprop on existing<Transaction />components -- add any missing chains towagmi-config.ts - Create a
TransactionFormcomponent using wagmi hooks (useWriteContract,useWaitForTransactionReceipt,useSwitchChain) - Component handles the full lifecycle: idle, pending wallet confirmation, confirming on-chain, success, error
- Replace all OnchainKit transaction imports (
Transaction,TransactionButton,TransactionStatus,TransactionSponsor, etc.) - Update the
callsarray format -- useaddress,abi,functionName,argswith properas consttyping - Map
onStatuscallback to the new lifecycle status names (init, pending, confirmed, success, error)
Validation gate: Run npm run build. Must pass before continuing. Document any errors in mistakes.md.
Step 5: Cleanup
- Search for any remaining
@coinbase/onchainkitimports -- there should be none - Optionally remove
@coinbase/onchainkitfrompackage.jsondependencies - Run final
npm run buildto verify everything works - Update
mistakes.mdwith final lessons learned
Troubleshooting
Build fails after provider migration
- Missing dependencies: Ensure
wagmi,viem,@tanstack/react-queryare installed - Type errors with wagmi config: Check that
chainsarray has at least one chain andtransportshas a matching entry - "use client" missing: Both the provider and wallet components must have
"use client"directive
MetaMask SDK react-native warning
- The warning
Can't resolve '@react-native-async-storage/async-storage'is harmless in web builds. It comes from MetaMask SDK and does not affect functionality.
Wallet won't connect
- Verify the wagmi config has the correct connectors configured
- Check that
WagmiProviderwraps the component tree before any wallet hooks are used - Ensure
QueryClientProvideris insideWagmiProvider
Transaction receipt stuck in pending
- Symptom: Transaction hash appears, tx confirms on-chain, but UI stays stuck on "Transaction in progress..." forever
- Cause:
useWaitForTransactionReceipthas no RPC to poll because the transaction's chain is missing from the wagmi config'schains+transports - Fix: (1) Add the target chain to
wagmi-config.tschains array AND transports object. (2) Always passchainIdtouseWaitForTransactionReceipt({ hash, chainId })so it polls the correct chain
Transaction targets wrong chain
- The
TransactionFormauto-switches chains, but the target chain must exist in the wagmi config'schainsarray andtransportsobject - Common: add
baseSepoliafor testnet transactions (chainId 84532)
Next.js page export restrictions
- Next.js only allows specific named exports from page files. Exporting contract call arrays or ABI constants from a page file will cause a build error
- Fix: make them non-exported
constdeclarations or move them to a separate module
ABI type errors after transaction migration
- When defining ABIs inline, use
as conston the array for proper type inference - Mark individual fields like
type: 'function' as constandstateMutability: 'nonpayable' as const
Existing wagmi setup detected
- If the project already wraps with
WagmiProvider, do NOT add another one - Instead, just update the existing wagmi config to include the needed connectors
- OnchainKit's provider detects and defers to existing wagmi providers -- the standalone setup should too
Important Notes
- Always use
wagmiandviemdirectly. Never import from@coinbase/onchainkit. - The
baseAccountconnector comes fromwagmi/connectors, not from a separate package. wagmi-config.tsmust include every chain the app transacts on. If the original OnchainKit<Transaction chainId={X} />used a specific chain, that chain must be in bothchainsandtransports. Without it,useWaitForTransactionReceiptwill hang forever.- If the project uses Tailwind, use Tailwind classes for the components. If not, adapt to inline styles or the project's existing styling approach (e.g., CSS Modules).
- Do not export contract call arrays, ABI constants, or other non-page values from Next.js page files. Use non-exported constants or a separate module.
- Inspect the OnchainKit source code in
node_modules/@coinbase/onchainkit/src/if you need to understand how a specific component works internally.