Best practices
Wallet connection
Do: await the SDK and connect on load.
const crackpay = await connectCrackPay();
Don't: show a connect button.
// Never do this in a Mini App
<button onClick={connect}>Connect wallet</button>
Don't: ask the user to sign a message. Message signing is not available, and the account address already identifies them.
Handle every connection state
Connecting, connected, opened outside CrackPay, and failed. See Setting up a React app.
Error handling
Match on error codes, never on message text.
import { ErrorCode, errorCode, isUserRejection } from "@crackpay/miniapp-sdk";
try {
await walletClient.writeContract(request);
} catch (error) {
if (isUserRejection(error)) return show("Cancelled.");
if (errorCode(error) === ErrorCode.Unauthorized) console.error("Not allowed for this app", error);
console.error(error);
show("The payment didn't go through. Please try again.");
}
- Treat a cancel as a cancel, not an error.
- Always log the original error.
- If a message says an operation was "submitted but never confirmed", ask the user to check their balance before retrying, and never retry automatically.
Money
- Keep amounts as
bigint; format only when rendering. - 6 decimals for tokens, 18 for a native
value. See Arc network. - Show dollars with two decimals.
- Approve exact amounts, never unlimited.
Transactions
- Show a waiting state only while the call is pending. It resolves when the payment is final; there are no confirmations to count.
- Disable the button while a transaction is in flight, so a double tap cannot pay twice.
- One call per transaction.
Contracts
- Accept smart-account callers. See Interacting with smart contracts.
- Verify every contract on the Arc explorer.
Security
- Validate every address and amount before sending.
- Never put secrets in
VITE_orNEXT_PUBLIC_variables. - Pin exact dependency versions and commit your lockfile.
- Only list hosts you control in
hostOrigins.
Performance
- Keep the first load light: CrackPay users are often on mobile data.
- Lazy-load below-the-fold content.