Skip to main content
This example demonstrates integration using the Coinbase Developer Platform (CDP) SDK with MPC-based key management and x402 v2. Perfect for backend applications requiring enterprise-grade security.

Overview

The CDP SDK provides server-side wallet management without exposing private keys. Keys are secured with Multi-Party Computation (MPC) technology. This example works with x402 v2 for both Base and Solana networks.

Features

  • MPC-based key management - No private keys in your code
  • Base (EVM) and Solana (SVM) network support
  • Enterprise security - Built by Coinbase
  • Server-side wallets - Perfect for backends
  • Type-safe TypeScript

Prerequisites

  • Node.js 18+
  • Coinbase CDP API credentials (Get them here)
  • USDC balance on Base or Solana
  • Existing CDP wallet address (Base) or Solana account

Installation

npm install @coinbase/cdp-sdk axios @x402/axios @x402/evm @x402/svm viem bs58

Quick Start

1. Get CDP Credentials

  1. Visit Coinbase Developer Platform
  2. Create an API key
  3. Save your API Key ID and Secret
  4. Create a wallet and fund it with USDC on Base

2. Set Up Environment

Create a .env file:
CDP_API_KEY_ID=your_api_key_id
CDP_API_KEY_SECRET=your_api_key_secret
CDP_WALLET_SECRET=your_wallet_secret
# For Base network
WALLET_ADDRESS=your_wallet_address
# For Solana network
SOLANA_ADDRESS=your_solana_address
# Common
RECEIVER=your_x_username
AMOUNT=0.01

3. Implement Base (EVM) Payment

Create base-send.ts:
import { CdpClient } from "@coinbase/cdp-sdk";
import axios from "axios";
import { privateKeyToAccount } from "viem/accounts";
import { x402Client, wrapAxiosWithPayment, decodePaymentResponseHeader } from "@x402/axios";
import { registerExactEvmScheme } from "@x402/evm/exact/client";

const apiKeyId = process.env.CDP_API_KEY_ID as string;
const apiKeySecret = process.env.CDP_API_KEY_SECRET as string;
const walletSecret = process.env.CDP_WALLET_SECRET as string;
const walletAddress = process.env.WALLET_ADDRESS as string;
const receiver = process.env.RECEIVER as string;
const amount = parseFloat(process.env.AMOUNT || "0.01");

async function sendPayment() {
  console.log("🚀 Starting Snack Money payment with CDP SDK (Base)\n");

  // Initialize CDP client
  const cdpClient = new CdpClient({
    apiKeyId,
    apiKeySecret,
    walletSecret,
  });
  console.log("✅ Initialized CDP client\n");

  // Export private key from CDP for x402 signing
  console.log("🔐 Exporting private key from CDP...\n");
  const privateKey = await cdpClient.evm.exportAccount({
    address: walletAddress
  });

  // Create viem account from private key
  const account = privateKeyToAccount(`0x${privateKey}`);
  console.log(`✅ Base signer created: ${account.address}\n`);

  // Create x402 client and register EVM scheme
  const x402 = new x402Client();
  registerExactEvmScheme(x402, { signer: account });
  console.log("✅ Registered EVM payment scheme\n");

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

  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 CDP SDK (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));
    }
  } catch (error) {
    console.error("❌ Payment failed:", error);
    throw error;
  }
}

sendPayment();

4. Implement Solana (SVM) Payment

Create solana-send.ts:
import { CdpClient } from "@coinbase/cdp-sdk";
import axios from "axios";
import { x402Client, wrapAxiosWithPayment, decodePaymentResponseHeader } from "@x402/axios";
import { registerExactSvmScheme } from "@x402/svm/exact/client";
import { createKeyPairSignerFromBytes } from "@solana/kit";
import bs58 from "bs58";

const apiKeyId = process.env.CDP_API_KEY_ID as string;
const apiKeySecret = process.env.CDP_API_KEY_SECRET as string;
const walletSecret = process.env.CDP_WALLET_SECRET as string;
const solanaAddress = process.env.SOLANA_ADDRESS as string;
const receiver = process.env.RECEIVER as string;
const amount = parseFloat(process.env.AMOUNT || "0.01");

async function sendPayment() {
  console.log("🚀 Starting Snack Money payment with CDP SDK (Solana)\n");

  // Initialize CDP client
  const cdpClient = new CdpClient({
    apiKeyId,
    apiKeySecret,
    walletSecret,
  });
  console.log("✅ Initialized CDP client\n");

  if (!solanaAddress) {
    console.error("❌ Missing SOLANA_ADDRESS in .env file!");
    console.log("\n💡 Run the create-solana-account.ts script first:");
    console.log("   npm run create-solana-account");
    process.exit(1);
  }

  console.log(`✅ Using CDP Solana account: ${solanaAddress}\n`);

  // Export private key from CDP for x402 signing
  console.log("🔐 Exporting private key from CDP...\n");
  const privateKeyBase58 = await cdpClient.solana.exportAccount({
    address: solanaAddress
  });

  // Create Solana signer from private key
  const privateKeyBytes = bs58.decode(privateKeyBase58);
  const solanaSigner = await createKeyPairSignerFromBytes(privateKeyBytes);
  console.log(`✅ Solana signer created: ${solanaSigner.address}\n`);

  // Create x402 client and register Solana scheme
  const client = new x402Client();
  registerExactSvmScheme(client, { signer: solanaSigner });
  console.log("✅ Registered Solana payment scheme\n");

  // 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 Solana...\n`);

  try {
    const response = await api.post("/payments/x/pay", {
      amount,
      currency: "USDC",
      receiver,
      description: "Payment via CDP SDK (Solana)"
    });

    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));
    }
  } catch (error) {
    console.error("❌ Payment failed:", error);
    throw error;
  }
}

sendPayment();

5. Run the Example

For Base network:
npm run base
# or
npx tsx base-send.ts
For Solana network:
npm run solana
# or
npx tsx solana-send.ts

Expected Output

🚀 Starting Snack Money payment with CDP SDK

✅ Initialized CDP client
✅ Retrieved CDP wallet
💸 Sending 0.01 USDC to @username on X...

✅ Payment successful!

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

How It Works

  1. Initialize CDP: Create CDP client with API credentials
  2. Get Wallet: Retrieve existing wallet by address
  3. Export Key: Export private key for transaction signing
  4. Create Account: Convert to viem account format
  5. Wrap Axios: Add x402 payment interceptor
  6. Send Payment: Make payment request

Why CDP SDK?

Security Benefits

  • No Private Key Management: Keys secured with MPC
  • Enterprise Grade: Built by Coinbase
  • Compliance: Meets regulatory requirements
  • Audit Trail: Complete transaction history

Best For

  • Backend applications
  • Enterprise deployments
  • High-value transactions
  • Compliance-focused apps

Supported Platforms

Send payments to:
// X (Twitter)
await api.post("/payments/x/pay", { amount, receiver, currency: "USDC" });

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

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

Error Handling

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 CDP-specific errors
  if (error.message.includes("wallet not found")) {
    console.error("CDP wallet not found. Check WALLET_ADDRESS");
  }
}

CDP Wallet Management

Creating a Wallet

const wallet = await coinbase.createWallet({
  networkId: "base-mainnet"
});
console.log("Wallet address:", wallet.getDefaultAddress());

Funding the Wallet

Transfer USDC to your wallet address on Base network before making payments.

Full Example Repository

View on GitHub → Includes:
  • Complete implementation
  • Environment setup
  • Configuration examples
  • Detailed README

Next Steps

Dependencies

{
  "dependencies": {
    "@coinbase/coinbase-sdk": "latest",
    "axios": "^1.6.0",
    "x402-axios": "latest",
    "viem": "^2.0.0"
  }
}

Learn More