> ## Documentation Index
> Fetch the complete documentation index at: https://docs.snack.money/llms.txt
> Use this file to discover all available pages before exploring further.

# Crossmint

> Smart contract wallets with x402 v2 protocol

This example demonstrates integration using **Crossmint Smart Wallets** with **x402 v2**. Perfect for applications needing smart wallet features and account abstraction.

## Overview

Integrate Snack Money payments using Crossmint's smart wallet infrastructure with x402 v2, using Crossmint's API for signing operations.

## Features

* ✅ **Base network** support
* ✅ **Smart wallet infrastructure** - Account abstraction
* ✅ **API-based signing** - Secure signature requests
* ✅ **Developer-controlled signing** - Full control
* ✅ **x402 v2 integration** - Latest protocol

## Prerequisites

* Node.js 18+
* Crossmint account ([Sign up](https://www.crossmint.com/))
* Crossmint API key
* Smart wallet with USDC balance on Base

## Installation

```bash theme={null}
npm install axios @x402/axios @x402/evm viem dotenv
```

## Quick Start

### 1. Get Crossmint Credentials

1. Visit [Crossmint Console](https://www.crossmint.com/console)
2. Create a project
3. Get your API key
4. Create a smart wallet

### 2. Set Up Environment

Create a `.env` file:

```bash theme={null}
CROSSMINT_API_KEY=your_api_key
WALLET_LOCATOR=your_wallet_locator
SMART_WALLET_ADDRESS=your_smart_wallet_address
RECEIVER=your_x_username
AMOUNT=0.01
```

<Note>
  **Important**: The `SMART_WALLET_ADDRESS` should have USDC balance on Base network.
</Note>

### 3. Implement Payment

Create `base-send.ts`:

```typescript theme={null}
import axios from "axios";
import { config } from "dotenv";
import { type Hex, type Address, type SignableMessage } from "viem";
import { toAccount } from "viem/accounts";
import { x402Client, wrapAxiosWithPayment, decodePaymentResponseHeader } from "@x402/axios";
import { registerExactEvmScheme } from "@x402/evm/exact/client";

config();

const crossmintApiKey = process.env.CROSSMINT_API_KEY as string;
const walletLocator = process.env.WALLET_LOCATOR as string;
const smartWalletAddress = process.env.SMART_WALLET_ADDRESS as string;
const receiver = process.env.RECEIVER as string;
const amount = parseFloat(process.env.AMOUNT || "0.01");

// Helper to request signatures from Crossmint API
async function requestCrossmintSignature(
  walletLocator: string,
  apiKey: string,
  signatureRequest: any
): Promise<Hex> {
  const createResponse = await axios.post(
    `https://www.crossmint.com/api/2022-06-09/wallets/${walletLocator}/signatures`,
    signatureRequest,
    {
      headers: {
        "X-API-KEY": apiKey,
        "Content-Type": "application/json"
      }
    }
  );

  const signatureId = createResponse.data.id;

  // Poll for signature
  let signature: string | null = null;
  let attempts = 0;
  const maxAttempts = 20;

  while (!signature && attempts < maxAttempts) {
    attempts++;
    const statusResponse = await axios.get(
      `https://www.crossmint.com/api/2022-06-09/wallets/${walletLocator}/signatures/${signatureId}`,
      { headers: { "X-API-KEY": apiKey } }
    );

    signature = statusResponse.data.outputSignature;
    if (signature) return signature as Hex;
    if (statusResponse.data.status === 'failed') {
      throw new Error(`Signature failed: ${JSON.stringify(statusResponse.data)}`);
    }
    await new Promise(resolve => setTimeout(resolve, 1000));
  }

  throw new Error(`Signature did not complete after ${maxAttempts} attempts`);
}

// Create a viem account that uses Crossmint's signature API
function createCrossmintAccount(
  address: Address,
  walletLocator: string,
  apiKey: string
) {
  const account = toAccount({
    address,
    async signMessage({ message }: { message: SignableMessage }): Promise<Hex> {
      const messageStr = typeof message === 'string' ? message : (message as any).raw || JSON.stringify(message);
      return requestCrossmintSignature(walletLocator, apiKey, {
        type: "evm-message",
        params: { message: messageStr, chain: "base" }
      });
    },
    signTransaction: async () => {
      throw new Error("Transaction signing not supported - use Crossmint transaction API");
    },
    signTypedData: async (typedData: any): Promise<Hex> => {
      return requestCrossmintSignature(walletLocator, apiKey, {
        type: "evm-typed-data",
        params: { typedData, chain: "base" }
      });
    }
  });

  return {
    ...account,
    sign: async ({ hash }: { hash: Hex }): Promise<Hex> => {
      return account.signMessage({ message: { raw: hash } as any });
    }
  } as any;
}

async function sendPayment() {
  console.log("🚀 Starting Snack Money payment with Crossmint Smart Wallet\n");
  console.log("ℹ️  Network: Base (EVM)\n");
  console.log(`✅ Smart Wallet Address: ${smartWalletAddress}`);
  console.log(`💡 Check balance: https://basescan.org/address/${smartWalletAddress}\n`);

  // Create Crossmint account
  const crossmintAccount = createCrossmintAccount(
    smartWalletAddress as Address,
    walletLocator,
    crossmintApiKey
  );

  // Create x402 client and register EVM scheme
  const client = new x402Client();
  registerExactEvmScheme(client, { signer: crossmintAccount });

  // Wrap axios with payment interceptor
  const api = wrapAxiosWithPayment(
    axios.create({ baseURL: "https://api.snack.money" }),
    client
  );

  console.log(`💸 Sending ${amount} USDC to @${receiver} on X via Base...\n`);

  try {
    const response = await api.post("/payments/x/pay", {
      amount,
      currency: "USDC",
      receiver,
      description: "Payment via Crossmint Smart Wallet (Base)"
    });

    console.log("✅ Payment successful!");
    console.log("\n📊 Response:", JSON.stringify(response.data, null, 2));

    const paymentResponseHeader = response.headers["payment-response"];
    if (paymentResponseHeader) {
      const paymentResponse = decodePaymentResponseHeader(paymentResponseHeader);
      console.log("\n🔐 Payment Response Details:", JSON.stringify(paymentResponse, null, 2));
    }

    if (response.data.data?.receipt) {
      console.log(`\n🧾 Receipt: ${response.data.data.receipt}`);
    }
  } catch (error: any) {
    console.error("❌ Payment failed:", error.response?.data || error.message);
    process.exit(1);
  }
}

sendPayment();
```

### 4. Run the Example

```bash theme={null}
npm run base
# or
npx tsx base-send.ts
```

## Expected Output

```
🚀 Starting Snack Money payment with Crossmint Smart Wallet

ℹ️  Network: Base (EVM)

✅ Smart Wallet Address: 0x...
💡 Check balance: https://basescan.org/address/0x...

🔐 Creating Crossmint account...

💸 Sending 0.01 USDC to @username on X via Base...

✅ Payment successful!

📊 Response: {
  "code": 200,
  "msg": "0.01 USDC sent successfully",
  "data": {
    "txn_id": "...",
    "amount": 0.01,
    "receipt": "https://snack.money/x/username?txn=..."
  }
}
```

## How It Works

1. **Create Crossmint Account**: Build a viem-compatible account that uses Crossmint's signature API
2. **Register x402 EVM Scheme**: Configure x402 client with the Crossmint signer
3. **Wrap Axios**: Add x402 payment interceptor
4. **Send Payment**: Make payment request
5. **Auto Signatures**: Crossmint API handles message and typed data signing
6. **Success**: Receive confirmation and receipt

## Why Crossmint?

### Benefits

* **Smart Wallets**: Advanced wallet capabilities
* **Account Abstraction**: Gasless transactions, batching
* **Viem Compatible**: Standard interface
* **Developer Controlled**: Full control over signing
* **Easy Integration**: Simple SDK

### Best For

* Apps needing smart wallet features
* Account abstraction requirements
* Gasless transactions
* Advanced wallet operations

## Smart Wallet Features

### Gasless Transactions

```typescript theme={null}
const wallet = await CrossmintSmartWallet.build({
  config: {
    chain: "base",
    apiKey: process.env.CROSSMINT_API_KEY!,
    gasless: true,  // Enable gasless transactions
  },
  signer: {
    type: "DEVELOPER_CONTROLLED",
    secret: process.env.CROSSMINT_SIGNER_SECRET!,
  },
});
```

### Transaction Batching

```typescript theme={null}
// Batch multiple operations
await wallet.sendBatchTransaction([
  { to: address1, data: "0x..." },
  { to: address2, data: "0x..." },
]);
```

## Supported Platforms

```typescript theme={null}
// X (Twitter)
await api.post("/payments/x/pay", {
  amount: 0.01,
  receiver: "username",
  currency: "USDC"
});

// Farcaster
await api.post("/payments/farcaster/pay", {
  amount: 0.5,
  receiver: "username",
  currency: "USDC"
});

// GitHub
await api.post("/payments/github/pay", {
  amount: 1.0,
  receiver: "username",
  currency: "USDC"
});
```

## Error Handling

```typescript theme={null}
try {
  const response = await api.post("/payments/x/pay", {
    amount: 0.01,
    currency: "USDC",
    receiver: "username"
  });
  console.log("Success:", response.data);
} catch (error) {
  console.error("Payment failed:", error);

  // Handle Crossmint-specific errors
  if (error.message.includes("insufficient funds")) {
    console.error("Smart wallet needs more USDC");
  }
}
```

## Wallet Management

### Check Balance

```typescript theme={null}
const balance = await wallet.getBalance();
console.log("Wallet balance:", balance);
```

### Get Wallet Info

```typescript theme={null}
console.log("Address:", wallet.address);
console.log("Chain:", wallet.chain);
```

## Full Example Repository

[View on GitHub →](https://github.com/snack-money/snack-money-examples/tree/main/crossmint)

Includes:

* Complete implementation
* Smart wallet setup
* Configuration guide
* Detailed README

## Next Steps

* [**Try axios**](/examples/axios) - Simplest integration
* [**Crossmint Docs**](https://docs.crossmint.com/) - Learn more
* [**API Reference**](/api-reference/introduction) - Complete API docs

## Dependencies

```json theme={null}
{
  "dependencies": {
    "axios": "^1.7.9",
    "@x402/axios": "^2.0.0",
    "@x402/evm": "^2.0.0",
    "viem": "^2.39.3",
    "dotenv": "^16.4.7"
  },
  "devDependencies": {
    "@types/node": "^22.0.0",
    "typescript": "^5.9.0"
  }
}
```

## Learn More

* [Crossmint Documentation](https://docs.crossmint.com/)
* [Smart Wallets Guide](https://docs.crossmint.com/wallets/smart-wallets)
* [@x402/axios Documentation](https://www.npmjs.com/package/@x402/axios)
* [x402 Protocol Specification](https://github.com/coinbase/x402)
* [Viem Documentation](https://viem.sh/)
