Overview

While Crossmint provides built-in wallet support, you can also integrate your own wallet solution using the payer prop. This is useful when:

  • You’re already using a wallet connection solution (like RainbowKit, Web3Modal, or ConnectKit)
  • You want to customize the transaction signing flow
  • You need to support specific wallets or chains

Quick Integration

Here’s a simple example using wagmi and viem:

import { CrossmintEmbeddedCheckout } from "@crossmint/client-sdk-react-ui";
import { useAccount, useWalletClient } from "wagmi";
import { Hex, parseTransaction } from "viem";

function Checkout() {
    const { data: walletClient } = useWalletClient();
    const { address } = useAccount();

    // Map of supported chains to their IDs
    const chainIds = {
        "base-sepolia": 84532,
        "polygon-amoy": 80002,
    } as const;

    if (!address || !walletClient) {
        return <p>Connect your wallet to continue</p>;
    }

    return (
        <CrossmintEmbeddedCheckout
            lineItems={{
                collectionLocator: "crossmint:__YOUR_COLLECTION_ID__",
                callData: {
                    totalPrice: "0.001",
                    quantity: 1,
                },
            }}
            payment={{
                crypto: {
                    // Enable crypto payment, this example only uses Crypto
                    enabled: true,
                    payer: {
                        address,
                        initialChain: "base-sepolia",
                        supportedChains: ["base-sepolia", "polygon-amoy"],
                        handleChainSwitch: async (chain) => {
                            await walletClient.switchChain({
                                id: chainIds[chain],
                            });
                        },
                        handleSignAndSendTransaction: async (serializedTx) => {
                            try {
                                const tx = parseTransaction(serializedTx as Hex);
                                const hash = await walletClient.sendTransaction({
                                    to: tx.to,
                                    value: tx.value,
                                    data: tx.data ?? "0x",
                                    gas: tx.gas,
                                    chainId: tx.chainId,
                                });

                                return { success: true, txId: hash };
                            } catch (error) {
                                return {
                                    success: false,
                                    errorMessage: error instanceof Error ? error.message : "Transaction failed",
                                };
                            }
                        },
                    },
                },
                // Disable fiat payment
                fiat: { enabled: false },
            }}
        />
    );
}

When the user clicks the Pay Button, our SDK will first call handleChainSwitch to ensure the correct network is set, then handleSignAndSendTransaction to complete the purchase.

Payer Configuration

The payer prop accepts the following configuration:

PropertyTypeDescription
addressstringThe wallet address of the payer
initialChainPayerSupportedBlockchainsThe initial blockchain (e.g. “polygon”, “ethereum”, “base-sepolia”)
supportedChainsPayerSupportedBlockchains[]Optional list of supported chains. Defaults to initialChain if not specified
handleChainSwitch(chain: PayerSupportedBlockchains) => Promise<void>Function to handle chain switching
handleSignAndSendTransaction(serializedTx: string) => Promise<TransactionResponse>Function to handle transaction signing and sending, where TransactionResponse is either { success: true, txId: string } or { success: false, errorMessage: string }

You can integrate Crossmint with popular Web3 solutions:

RainbowKit

import { useConnectModal } from "@rainbow-me/rainbowkit";

// Similar implementation as above, but using RainbowKit's hooks

Web3Modal

import { useWeb3Modal } from "@web3modal/react";

// Similar implementation as above, but using Web3Modal's hooks

Best Practices

  1. Error Handling: Always return clear error messages in handleSignAndSendTransaction
  2. Chain Support: Be explicit about supported chains to avoid runtime errors
  3. User Experience: Show loading states during chain switches and transactions
  4. Wallet Connection: Ensure wallet is connected before showing checkout