Loading...
Loading...
Use this skill when you are asked to adapt an existing web app to work as a World App mini app, or to share code between a web app and a mini app. This skill covers the technical steps of migration, common issues, and debugging tips. There will be some changes required to contracts and frontend code, but the overall architecture and user experience can remain largely unchanged.
npx skill4agent add worldcoin/minikit-js web-to-miniappnpm install @worldcoin/minikit-js @worldcoin/minikit-reactwindow.WorldAppssr: false// src/app/page.tsx
'use client';
import dynamic from 'next/dynamic';
const App = dynamic(() => import('../components/App'), { ssr: false });
export default function Page() {
return <App />;
}src/components/App.tsxsrc/app/providers.tsx'use client';
import { MiniKitProvider } from '@worldcoin/minikit-js/minikit-provider';
export default function Providers({ children }: { children: React.ReactNode }) {
return <MiniKitProvider>{children}</MiniKitProvider>;
}src/app/layout.tsximport Providers from './providers';
// ...
<body>
<Providers>{children}</Providers>
</body>;MiniKit.isInWorldApp()getWorldAppProvider()window.ethereumimport { MiniKit } from '@worldcoin/minikit-js';
import { getWorldAppProvider } from '@worldcoin/minikit-js';
import { createWalletClient, custom } from 'viem';
import { worldchain } from 'viem/chains';
const provider = MiniKit.isInWorldApp()
? getWorldAppProvider()
: window.ethereum;
const walletClient = createWalletClient({
chain: worldchain,
transport: custom(provider),
});getWorldAppProvider()eth_requestAccountsMiniKit.walletAuth()eth_sendTransactionMiniKit.sendTransaction()userOpHasheth_chainId0x1e0writeContractreadContractapprove()transferFrom()sendTransactionimport { MiniKit } from '@worldcoin/minikit-js';
import { encodeFunctionData } from 'viem';
await MiniKit.sendTransaction({
chainId: 480,
transactions: [
{
to: TOKEN,
data: encodeFunctionData({
abi: erc20Abi,
functionName: 'approve',
args: [CONTRACT, amount],
}),
},
{
to: CONTRACT,
data: encodeFunctionData({
abi: contractAbi,
functionName: 'swap',
args: [amount],
}),
},
],
});userOpHashuseUserOperationReceipt@worldcoin/minikit-reactimport { useUserOperationReceipt } from '@worldcoin/minikit-react';
import { createPublicClient, http } from 'viem';
import { worldchain } from 'viem/chains';
const client = createPublicClient({
chain: worldchain,
transport: http(),
});
const { poll, isLoading } = useUserOperationReceipt({ client });
// After sendTransaction:
const result = await MiniKit.sendTransaction({ ... });
await poll(result.data.userOpHash);invalid_contract| Issue | Symptom | Fix |
|---|---|---|
| SSR hydration mismatch | Buttons render but clicks do nothing | |
| Always | Use |
Permit2 uses | Silent overflow | Cast explicitly |
| | Use |
| Missing contract whitelist | | Add to Developer Portal permissions |
<!-- In layout.tsx body -->
<script src="https://cdn.jsdelivr.net/npm/eruda"></script>
<script>
eruda.init();
</script>