Skip to main content
Crossmint provides seamless support for multiple blockchain networks, allowing you to build applications that work across EVM-compatible chains and Solana.

Supported Chains

Crossmint supports a wide range of blockchain networks:

Ethereum

Mainnet & Sepolia testnet

Polygon

Mainnet & Amoy testnet

Base

Mainnet & Sepolia testnet

Solana

Mainnet & Devnet

Arbitrum

One & Sepolia

Optimism

Mainnet & Sepolia

Chain Identifiers

Each chain has a unique identifier used throughout the SDK:

EVM Chains

"ethereum"           // Ethereum Mainnet
"ethereum-sepolia"   // Ethereum Sepolia Testnet
"polygon"            // Polygon Mainnet
"polygon-amoy"       // Polygon Amoy Testnet
"base"               // Base Mainnet
"base-sepolia"       // Base Sepolia Testnet
"arbitrum"           // Arbitrum One
"arbitrum-sepolia"   // Arbitrum Sepolia
"optimism"           // Optimism Mainnet
"optimism-sepolia"   // Optimism Sepolia

Non-EVM Chains

"solana"             // Solana Mainnet
"solana-devnet"      // Solana Devnet

Creating Multi-Chain Wallets

Create wallets for users on different chains:
1

Initialize the SDK

import { createCrossmint } from "@crossmint/common-sdk-base";
import { CrossmintWallets } from "@crossmint/wallets-sdk";

const crossmint = createCrossmint({
  apiKey: "YOUR_API_KEY",
});

const wallets = CrossmintWallets.from(crossmint);
2

Create wallets on different chains

const userId = "user-123";

// Ethereum wallet
const ethWallet = await wallets.getOrCreateWallet({
  chain: "ethereum-sepolia",
  signer: {
    type: "api-key",
    locator: userId,
  },
});

// Polygon wallet
const polygonWallet = await wallets.getOrCreateWallet({
  chain: "polygon-amoy",
  signer: {
    type: "api-key",
    locator: userId,
  },
});

// Solana wallet
const solanaWallet = await wallets.getOrCreateWallet({
  chain: "solana-devnet",
  signer: {
    type: "api-key",
    locator: userId,
  },
});

console.log("ETH address:", ethWallet.address);
console.log("Polygon address:", polygonWallet.address);
console.log("Solana address:", solanaWallet.address);
EVM chains (Ethereum, Polygon, Base, etc.) will generate the same address for a given user. Solana wallets have different addresses.

Chain-Specific Operations

EVM Chains

Work with Ethereum-compatible chains:
import { EVMWallet } from "@crossmint/wallets-sdk";

const wallet = await wallets.getOrCreateWallet({
  chain: "polygon-amoy",
  signer: { type: "api-key", locator: userId },
});

const evmWallet = EVMWallet.from(wallet);

// Send native currency (MATIC)
const tx = await evmWallet.sendTransaction({
  to: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
  value: "0.1",
});

// Call smart contract
const contractTx = await evmWallet.sendTransaction({
  to: "0xContractAddress",
  abi: [...], // Contract ABI
  functionName: "mint",
  args: ["0xRecipient", 1],
});

// Sign message
const signature = await evmWallet.signMessage({
  message: "Hello from Polygon!",
});

Solana

Work with Solana blockchain:
import { SolanaWallet } from "@crossmint/wallets-sdk";
import { Transaction, SystemProgram, PublicKey } from "@solana/web3.js";

const wallet = await wallets.getOrCreateWallet({
  chain: "solana-devnet",
  signer: { type: "api-key", locator: userId },
});

const solanaWallet = SolanaWallet.from(wallet);

// Create transaction
const transaction = new Transaction().add(
  SystemProgram.transfer({
    fromPubkey: new PublicKey(solanaWallet.address),
    toPubkey: new PublicKey("recipient-address"),
    lamports: 1000000, // 0.001 SOL
  })
);

// Send transaction
const serialized = transaction.serialize().toString("base64");
const result = await solanaWallet.sendTransaction({
  serializedTransaction: serialized,
});

console.log("Transaction hash:", result.hash);

Multi-Chain NFT Checkout

Accept payments for NFTs on any supported chain:

Ethereum NFT

import { CrossmintHostedCheckout } from "@crossmint/client-sdk-react-ui";

function EthereumNFTCheckout() {
  return (
    <CrossmintHostedCheckout
      lineItems={{
        collectionLocator: "crossmint:ethereum-collection-id",
        callData: {
          totalPrice: "0.01",
          quantity: 1,
        },
      }}
      payment={{
        fiat: { enabled: true },
        crypto: { enabled: true },
      }}
    />
  );
}

Solana NFT

function SolanaNFTCheckout() {
  return (
    <CrossmintHostedCheckout
      lineItems={{
        tokenLocator: "solana:token-mint-address",
        executionParameters: {
          mode: "exact-in",
          amount: "1",
        },
      }}
      payment={{
        fiat: { enabled: true },
        crypto: { enabled: true },
      }}
    />
  );
}

Polygon NFT

function PolygonNFTCheckout() {
  return (
    <CrossmintEmbeddedCheckout
      lineItems={{
        collectionLocator: "crossmint:polygon-collection-id",
        callData: {
          totalPrice: "0.001",
          quantity: 1,
        },
      }}
      recipient={{
        walletAddress: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
      }}
      payment={{
        fiat: { enabled: true },
      }}
    />
  );
}

Checking Balances Across Chains

Retrieve balances for wallets on different chains:
async function getAllBalances(userId: string) {
  const chains = [
    "ethereum-sepolia",
    "polygon-amoy",
    "base-sepolia",
    "solana-devnet",
  ] as const;

  const balances = await Promise.all(
    chains.map(async (chain) => {
      const wallet = await wallets.getOrCreateWallet({
        chain,
        signer: { type: "api-key", locator: userId },
      });

      const balance = await wallet.getBalance();

      return {
        chain,
        address: wallet.address,
        native: balance.native.formatted,
        symbol: balance.native.symbol,
      };
    })
  );

  return balances;
}

// Usage
const userBalances = await getAllBalances("user-123");
console.log(userBalances);
// [
//   { chain: "ethereum-sepolia", address: "0x...", native: "0.5", symbol: "ETH" },
//   { chain: "polygon-amoy", address: "0x...", native: "10.0", symbol: "MATIC" },
//   { chain: "base-sepolia", address: "0x...", native: "1.2", symbol: "ETH" },
//   { chain: "solana-devnet", address: "...", native: "2.5", symbol: "SOL" },
// ]

Chain Detection

Detect which chain a wallet belongs to:
import { isValidEvmAddress, isValidSolanaAddress } from "@crossmint/common-sdk-base";

function detectChainType(address: string) {
  if (isValidEvmAddress(address)) {
    return "evm";
  } else if (isValidSolanaAddress(address)) {
    return "solana";
  }
  return "unknown";
}

const chainType = detectChainType("0x742d35Cc...");
console.log(chainType); // "evm"

Token Locators

Reference tokens across different chains using locators:
// Ethereum token
const ethToken = "ethereum:0x1234567890123456789012345678901234567890";

// Polygon token
const polygonToken = "polygon:0x1234567890123456789012345678901234567890";

// Solana token
const solanaToken = "solana:TokenMintAddressHere123456789";

// Use in checkout
<CrossmintEmbeddedCheckout
  lineItems={{
    tokenLocator: polygonToken,
    executionParameters: {
      mode: "exact-in",
      amount: "1",
    },
  }}
/>

Cross-Chain Transactions

Crossmint handles each blockchain separately. For true cross-chain transfers (bridging), integrate additional bridge protocols.
Example multi-chain workflow:
async function multiChainWorkflow(userId: string) {
  // 1. Create wallets on multiple chains
  const ethWallet = await wallets.getOrCreateWallet({
    chain: "ethereum-sepolia",
    signer: { type: "api-key", locator: userId },
  });

  const solWallet = await wallets.getOrCreateWallet({
    chain: "solana-devnet",
    signer: { type: "api-key", locator: userId },
  });

  // 2. Check balances
  const ethBalance = await ethWallet.getBalance();
  const solBalance = await solWallet.getBalance();

  console.log(`ETH Balance: ${ethBalance.native.formatted} ETH`);
  console.log(`SOL Balance: ${solBalance.native.formatted} SOL`);

  // 3. Execute chain-specific transactions
  if (parseFloat(ethBalance.native.raw) > 0) {
    const evmWallet = EVMWallet.from(ethWallet);
    await evmWallet.sendTransaction({
      to: "0xRecipient",
      value: "0.001",
    });
  }

  if (parseFloat(solBalance.native.raw) > 0) {
    const solanaWallet = SolanaWallet.from(solWallet);
    // Execute Solana transaction
  }
}

Best Practices

1

Use consistent user identifiers

Use the same user ID across all chains for easier management:
const userId = "user-123";

// All chains use the same userId
const ethWallet = await wallets.getOrCreateWallet({
  chain: "ethereum-sepolia",
  signer: { type: "api-key", locator: userId },
});

const solWallet = await wallets.getOrCreateWallet({
  chain: "solana-devnet",
  signer: { type: "api-key", locator: userId },
});
2

Cache wallet addresses by chain

Store addresses per chain to minimize API calls:
interface UserWallets {
  userId: string;
  ethereum?: string;
  polygon?: string;
  solana?: string;
}

// Store in database
await db.wallets.upsert({
  userId: "user-123",
  ethereum: ethWallet.address,
  polygon: polygonWallet.address,
  solana: solanaWallet.address,
});
3

Handle chain-specific errors

try {
  const wallet = await wallets.getOrCreateWallet({
    chain: "ethereum-sepolia",
    signer: { type: "api-key", locator: userId },
  });
} catch (error) {
  if (error.message.includes("insufficient funds")) {
    // Handle insufficient funds on this specific chain
  } else if (error.message.includes("rate limit")) {
    // Handle rate limiting
  }
}
4

Test on testnets first

Always test multi-chain functionality on testnets before production:
  • ethereum-sepolia for Ethereum
  • polygon-amoy for Polygon
  • base-sepolia for Base
  • solana-devnet for Solana

Chain-Specific Considerations

Gas Fees

Different chains have different gas fee structures:
ChainNative TokenTypical Gas Fee
EthereumETHHigh ($5-50+)
PolygonMATICVery Low ($0.01-0.10)
BaseETHLow ($0.10-1.00)
SolanaSOLVery Low ($0.0001-0.001)

Transaction Speed

ChainBlock TimeFinality
Ethereum~12 seconds~2-3 minutes
Polygon~2 seconds~30 seconds
Base~2 seconds~30 seconds
Solana~0.4 seconds~6 seconds

Next Steps

Custom Transactions

Build custom transactions for each chain

Embedded Wallets

Manage wallets across multiple chains

Build docs developers (and LLMs) love