Skip to main content

Transaction status

On Arc, a transaction is final in under a second, and CrackPay waits for it before answering. So the lifecycle in your app is short:

StateWhenShow
idleBefore the user actsYour button
waitingThe call is pending: CrackPay is showing its confirmation, then sendingA disabled button with progress
doneThe call resolved with a hashSuccess. It is final.
cancelledRejected with 4001"Cancelled."
failedRejected with anything else"The payment didn't go through."
type Status = "idle" | "waiting" | "done" | "cancelled" | "failed";

async function pay() {
setStatus("waiting");
try {
const hash = await walletClient.writeContract(request);
setReceipt(hash);
setStatus("done");
} catch (error) {
console.error(error);
setStatus(isUserRejection(error) ? "cancelled" : "failed");
}
}

No polling​

You do not need waitForTransactionReceipt or confirmation counts: when the call resolves, the transaction is already final. If you want the receipt for its events, fetch it once:

const receipt = await publicClient.getTransactionReceipt({ hash });

Its from is a bundler and its to is the ERC-4337 EntryPoint; your contract's events are in logs.

Linking to the explorer​

// `chain` from connectCrackPay(), or getArcChain(await provider.request({ method: "eth_chainId" }))
const url = `${chain.explorerUrl}/tx/${hash}`;