Bringing an existing dApp
You can make an existing web3 app run inside CrackPay. Its screens and logic carry over; what changes is how it reaches the wallet, the chain it uses, and a few assumptions about accounts and gas.
What changes
| A typical dApp | Inside CrackPay | |
|---|---|---|
| Wallet | A wallet picker and a "Connect wallet" button | Connected on load through @crackpay/miniapp-sdk |
| Detection | window.ethereum at page load | await getCrackPayProvider() |
| Chain | Whatever it targets | Arc mainnet 5042 (or Arc Testnet 5042002), read from the provider |
| Gas | Paid by the user, estimated by the app | Sponsored by CrackPay, nothing to set |
| Account | A private-key wallet | A passkey smart account |
| Stablecoins | Varies | USDC and EURC on Arc |
| Signing | Messages and typed data | Not available |
| Container | A browser tab | A frame inside the CrackPay page |
Steps
- Find the wallet layer. Search for
window.ethereum, connect buttons, wallet pickers, chain switching, gas estimation,signMessageandsignTypedData. - Install the SDK:
npm install @crackpay/miniapp-sdk. - Replace provider access with
connectCrackPay()oruseCrackPay(), and move startup code behind the promise. See Wallet connection. - Remove the connect button and the wallet picker when running in CrackPay.
- Switch the chain to the Arc network CrackPay reports (
arcorarcTestnet) and remove chain switching. - Remove gas handling: fee estimates, gas fields and any gas reserve.
- Check token amounts. Arc's USDC is 6 decimals as a token and 18 as a native
value. Replace direct token transfers with a call to your own contract. See Arc network. - Remove signatures. Identify users by account address; replace permits and signed orders with on-chain calls.
- Deploy your contracts on Arc and check they accept smart-account callers. See Interacting with smart contracts.
- Allow framing by CrackPay; expect partitioned storage. See Deployment.
- Test in Developer mode and submit.
Running inside and outside CrackPay
Pick the wallet once at startup and keep the rest of the app unaware of it:
import { connectCrackPay } from "@crackpay/miniapp-sdk/viem";
export async function connectWallet() {
// Inside CrackPay: connected at once, no prompt.
const crackpay = await connectCrackPay();
if (crackpay) return { wallet: "crackpay" as const, ...crackpay };
// Anywhere else: your usual wallet flow.
return connectWithYourUsualWalletFlow();
}
Outside a frame, connectCrackPay() resolves to null immediately, so the
normal flow is not delayed. Keep per-environment values (chain, token addresses,
contracts) in one table keyed by wallet, and branch nowhere else.