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

# index

# Coinbase Developer Platform (CDP) TypeScript SDK

## Table of Contents

* [CDP SDK](#cdp-sdk)
* [Documentation](#documentation)
* [Installation](#installation)
* [API Keys](#api-keys)
* [Usage](#usage)
  * [Initialization](#initialization)
  * [Creating Accounts](#creating-evm-or-solana-accounts)
  * [Updating Accounts](#updating-evm-or-solana-accounts)
  * [Testnet Faucet](#testnet-faucet)
  * [Sending Transactions](#sending-transactions)
  * [EIP-7702 delegation](#eip-7702-delegation)
  * [EVM Smart Accounts](#evm-smart-accounts)
  * [EVM Swaps](#evm-swaps)
  * [Transferring Tokens](#transferring-tokens)
  * [Account Actions](#account-actions)
* [Policy Management](#policy-management)
  * [End User Policies](#end-user-policies)
* [End-user Management](#end-user-management)
  * [Create End User](#create-end-user)
  * [Import End User](#import-end-user)
  * [Add EVM Account to End User](#add-evm-account-to-end-user)
  * [Add EVM Smart Account to End User](#add-evm-smart-account-to-end-user)
  * [Add Solana Account to End User](#add-solana-account-to-end-user)
  * [Validate Access Token](#validate-access-token)
* [Delegated Signing Operations](#delegated-signing-operations)
  * [Revoke Delegation](#revoke-delegation)
  * [EVM Signing](#evm-signing)
  * [EVM Sending](#evm-sending)
  * [EVM EIP-7702 Delegation](#evm-eip-7702-delegation)
  * [Solana Signing](#solana-signing)
  * [Solana Sending](#solana-sending)
* [Webhooks](#webhooks)
  * [Create Subscription](#create-subscription)
* [x402 Payment Protocol](#x402-payment-protocol)
  * [Pay for an x402-protected API](#pay-for-an-x402-protected-api)
  * [Apply spend controls](#apply-spend-controls)
  * [Gate an HTTP endpoint](#gate-an-http-endpoint)
  * [Use the CDP-hosted facilitator](#use-the-cdp-hosted-facilitator)
  * [Use a CDP wallet with an existing x402 client](#use-a-cdp-wallet-with-an-existing-x402-client)
  * [Sign an x402 payment payload directly](#sign-an-x402-payment-payload-directly)
* [Authentication tools](#authentication-tools)
* [Error Reporting](#error-reporting)
* [Usage Tracking](#usage-tracking)
* [License](#license)
* [Support](#support)
* [Security](#security)
* [FAQ](#faq)

> \[!TIP]
>
> If you're looking to contribute to the SDK, please see the [Contributing Guide](https://github.com/coinbase/cdp-sdk/blob/main/typescript/CONTRIBUTING).

## CDP SDK

This module contains the TypeScript CDP SDK, which is a library that provides a client for interacting with the [Coinbase Developer Platform (CDP)](https://docs.cdp.coinbase.com/). It includes a CDP Client for interacting with EVM and Solana APIs to create accounts and send transactions, policy APIs to govern transaction permissions, as well as authentication tools for interacting directly with the CDP APIs.

## Documentation

CDP SDK has [auto-generated docs for the Typescript SDK](https://docs.cdp.coinbase.com/sdks/cdp-sdks-v2/typescript).

Further documentation is also available on the CDP docs website:

* [Wallet API v2](https://docs.cdp.coinbase.com/wallet-api-v2/docs/welcome)
* [API Reference](https://docs.cdp.coinbase.com/api-v2/docs/welcome)

## Installation

```bash theme={null}
npm install @coinbase/cdp-sdk
```

## API Keys

To start, [create a CDP API Key](https://portal.cdp.coinbase.com/access/api). Save the `API Key ID` and `API Key Secret` for use in the SDK. You will also need to create a wallet secret in the Portal to sign transactions.

Most CDP API endpoints require API key credentials. Public (unauthenticated) endpoints can be called without credentials, and authenticated endpoints will raise a clear request-time error if credentials are missing.

## Usage

### Initialization

#### Load client config from shell

One option is to export your CDP API Key and Wallet Secret as environment variables:

```bash theme={null}
export CDP_API_KEY_ID="YOUR_API_KEY_ID"
export CDP_API_KEY_SECRET="YOUR_API_KEY_SECRET"
export CDP_WALLET_SECRET="YOUR_WALLET_SECRET"
```

Then, initialize the client:

```typescript theme={null}
import { CdpClient } from "@coinbase/cdp-sdk";

const cdp = new CdpClient();
```

If you are only calling public (unauthenticated) endpoints, constructing `CdpClient` without credentials is supported:

```typescript theme={null}
import { CdpClient } from "@coinbase/cdp-sdk";

const cdp = new CdpClient();
```

#### Load client config from `.env` file

Another option is to save your CDP API Key and Wallet Secret in a `.env` file:

```bash theme={null}
touch .env
echo "CDP_API_KEY_ID=YOUR_API_KEY_ID" >> .env
echo "CDP_API_KEY_SECRET=YOUR_API_KEY_SECRET" >> .env
echo "CDP_WALLET_SECRET=YOUR_WALLET_SECRET" >> .env
```

Then, load the client config from the `.env` file:

```typescript theme={null}
import { CdpClient } from "@coinbase/cdp-sdk";
import dotenv from "dotenv";

dotenv.config();

const cdp = new CdpClient();
```

#### Pass the API Key and Wallet Secret to the client

Another option is to directly pass the API Key and Wallet Secret to the client:

```typescript theme={null}
const cdp = new CdpClient({
  apiKeyId: "YOUR_API_KEY_ID",
  apiKeySecret: "YOUR_API_KEY_SECRET",
  walletSecret: "YOUR_WALLET_SECRET",
});
```

### Client Lifecycle

The CDP client wraps an HTTP client (Axios) and should be created once and reused throughout your application's lifecycle. The underlying HTTP client handles connection pooling automatically, so there's no need to recreate the client per request—doing so would be less efficient.

* **Long-lived services**: Create a single client instance at startup
* **Serverless/request-based runtimes**: Create once per cold start, or use a module-level singleton
* **Concurrency**: The client is safe to use across concurrent async operations

### Creating EVM or Solana accounts

#### Create an EVM account as follows:

```typescript theme={null}
const account = await cdp.evm.createAccount();
```

#### Import an EVM account as follows:

```typescript theme={null}
const account = await cdp.evm.importAccount({
  privateKey: "0x123456",
  name: "MyAccount",
});
```

#### Create a Solana account as follows:

```typescript theme={null}
const account = await cdp.solana.createAccount();
```

#### Import a Solana account as follows:

```typescript theme={null}
const account = await cdp.solana.importAccount({
  privateKey: "3MLZ...Uko8zz",
  name: "MyAccount",
});
```

### Exporting EVM or Solana accounts

#### Export an EVM account as follows:

```typescript theme={null}
// by name
const privateKey = await cdp.evm.exportAccount({
  name: "MyAccount",
});

// by address
const privateKey = await cdp.evm.exportAccount({
  address: "0x123",
});
```

#### Export a Solana account as follows:

```typescript theme={null}
// by name
const privateKey = await cdp.solana.exportAccount({
  name: "MyAccount",
});

// by address
const privateKey = await cdp.solana.exportAccount({
  address: "Abc",
});
```

#### Get or Create an EVM account as follows:

```typescript theme={null}
const account = await cdp.evm.getOrCreateAccount({
  name: "Account1",
});
```

#### Get or Create a Solana account as follows:

```typescript theme={null}
const account = await cdp.solana.getOrCreateAccount({
  name: "Account1",
});
```

#### Get or Create a Smart Account as follows:

```typescript theme={null}
const owner = await cdp.evm.createAccount();
const account = await cdp.evm.getOrCreateSmartAccount({
  name: "Account1",
  owner,
});
```

### Creating EVM or Solana accounts with policies

#### Create an EVM account with policy as follows:

```typescript theme={null}
const account = await cdp.evm.createAccount({
  name: "AccountWithPolicy",
  accountPolicy: "abcdef12-3456-7890-1234-567890123456",
});
```

#### Create a Solana account with policy as follows:

```typescript theme={null}
const account = await cdp.solana.createAccount({
  name: "AccountWithPolicy",
  accountPolicy: "abcdef12-3456-7890-1234-567890123456",
});
```

### Updating EVM or Solana accounts

#### Update an EVM account as follows:

```typescript theme={null}
const account = await cdp.evm.updateAccount({
  addresss: account.address,
  update: {
    name: "Updated name",
    accountPolicy: "1622d4b7-9d60-44a2-9a6a-e9bbb167e412",
  },
});
```

#### Update a Solana account as follows:

```typescript theme={null}
const account = await cdp.solana.updateAccount({
  addresss: account.address,
  update: {
    name: "Updated name",
    accountPolicy: "1622d4b7-9d60-44a2-9a6a-e9bbb167e412",
  },
});
```

### Testnet faucet

You can use the faucet function to request testnet ETH or SOL from the CDP.

#### Request testnet ETH as follows:

```typescript theme={null}
const faucetResp = await cdp.evm.requestFaucet({
  address: evmAccount.address,
  network: "base-sepolia",
  token: "eth",
});
```

#### Request testnet SOL as follows:

```typescript theme={null}
const faucetResp = await cdp.solana.requestFaucet({
  address: fromAddress,
  token: "sol",
});
```

### Sending transactions

#### EVM

You can use CDP SDK to send transactions on EVM networks.

```typescript theme={null}
import { CdpClient } from "@coinbase/cdp-sdk";
import { parseEther, createPublicClient, http } from "viem";
import { baseSepolia } from "viem/chains";

const publicClient = createPublicClient({
  chain: baseSepolia,
  transport: http(),
});

const cdp = new CdpClient();

const account = await cdp.evm.createAccount();

const faucetResp = await cdp.evm.requestFaucet({
  address: account.address,
  network: "base-sepolia",
  token: "eth",
});

const faucetTxReceipt = await publicClient.waitForTransactionReceipt({
  hash: faucetResp.transactionHash,
});

const { transactionHash } = await cdp.evm.sendTransaction({
  address: account.address,
  network: "base-sepolia",
  transaction: {
    to: "0x4252e0c9A3da5A2700e7d91cb50aEf522D0C6Fe8",
    value: parseEther("0.000001"),
  },
});

await publicClient.waitForTransactionReceipt({ hash: transactionHash });

console.log(
  `Transaction confirmed! Explorer link: https://sepolia.basescan.org/tx/${transactionHash}`,
);
```

CDP SDK is fully viem-compatible, so you can optionally use a `walletClient` to send transactions.

```typescript theme={null}
import { CdpClient } from "@coinbase/cdp-sdk";
import { parseEther, createPublicClient, http, createWalletClient, toAccount } from "viem";
import { baseSepolia } from "viem/chains";

const publicClient = createPublicClient({
  chain: baseSepolia,
  transport: http(),
});

const cdp = new CdpClient();

const account = await cdp.evm.createAccount();

const faucetResp = await cdp.evm.requestFaucet({
  address: account.address,
  network: "base-sepolia",
  token: "eth",
});

const faucetTxReceipt = await publicClient.waitForTransactionReceipt({
  hash: faucetResp.transactionHash,
});

const walletClient = createWalletClient({
  account: toAccount(serverAccount),
  chain: baseSepolia,
  transport: http(),
});

// Step 3: Sign the transaction with CDP and broadcast it using the wallet client.
const hash = await walletClient.sendTransaction({
  to: "0x4252e0c9A3da5A2700e7d91cb50aEf522D0C6Fe8",
  value: parseEther("0.000001"),
});

console.log(`Transaction confirmed! Explorer link: https://sepolia.basescan.org/tx/${hash}`);
```

#### Solana

You can use CDP SDK to send transactions on Solana.

For complete examples, check out [sendTransaction.ts](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/solana/sendTransaction.ts), [sendManyTransactions.ts](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/solana/sendManyTransactions.ts), and [sendManyBatchedTransactions.ts](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/solana/sendManyBatchedTransactions.ts).

```typescript theme={null}
import { CdpClient } from "@coinbase/cdp-sdk";
import "dotenv/config";

import {
  address as solanaAddress,
  appendTransactionMessageInstructions,
  compileTransaction,
  createNoopSigner,
  createSolanaRpc,
  createTransactionMessage,
  getBase64EncodedWireTransaction,
  pipe,
  setTransactionMessageFeePayer,
  setTransactionMessageLifetimeUsingBlockhash,
} from "@solana/kit";
import { getTransferSolInstruction } from "@solana-program/system";

const cdp = new CdpClient();

const account = await cdp.solana.createAccount();

await cdp.solana.requestFaucet({
  address: account.address,
  token: "sol",
});

const rpc = createSolanaRpc("https://api.devnet.solana.com");
const {
  value: { blockhash, lastValidBlockHeight },
} = await rpc.getLatestBlockhash().send();

const instruction = getTransferSolInstruction({
  source: createNoopSigner(solanaAddress(account.address)),
  destination: solanaAddress("3KzDtddx4i53FBkvCzuDmRbaMozTZoJBb1TToWhz3JfE"),
  amount: 10000n,
});

const txMsg = pipe(
  createTransactionMessage({ version: 0 }),
  tx => setTransactionMessageFeePayer(solanaAddress(account.address), tx),
  tx => setTransactionMessageLifetimeUsingBlockhash({ blockhash, lastValidBlockHeight }, tx),
  tx => appendTransactionMessageInstructions([instruction], tx),
);

const serializedTx = getBase64EncodedWireTransaction(compileTransaction(txMsg));

console.log("Transaction serialized successfully");

const txResult = await cdp.solana.sendTransaction({
  network: "solana-devnet",
  transaction: serializedTx,
});

console.log(
  `Transaction confirmed! Explorer link: https://explorer.solana.com/tx/${txResult.signature}?cluster=devnet`,
);
```

To have CDP sponsor the transaction fees, pass `useCdpSponsor: true`. When enabled, CDP pays the network fee so the sender does not need SOL for fees.

```typescript theme={null}
const txResult = await cdp.solana.sendTransaction({
  network: "solana-devnet",
  transaction: serializedTx,
  useCdpSponsor: true,
});
```

### EIP-7702 delegation

You can create an [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) delegation for an existing EOA, upgrading it with smart account capabilities on supported networks. The delegated EOA can then use batched transactions and gas sponsorship via paymaster.

```typescript theme={null}
import { CdpClient } from "@coinbase/cdp-sdk";
import { createPublicClient, http } from "viem";
import { baseSepolia } from "viem/chains";

const cdp = new CdpClient();
const publicClient = createPublicClient({
  chain: baseSepolia,
  transport: http(),
});

const account = await cdp.evm.getOrCreateAccount({ name: "MyAccount" });

const { delegationOperationId } = await cdp.evm.createEvmEip7702Delegation({
  address: account.address,
  network: "base-sepolia",
  enableSpendPermissions: false, // optional, defaults to false
  idempotencyKey: "optional-uuid", // optional
});

// Wait for the delegation operation to complete
const delegationOperation = await cdp.evm.waitForEvmEip7702DelegationOperationStatus({
  delegationOperationId,
});
console.log(`Delegation confirmed (status: ${delegationOperation.status})`);
```

For a runnable example that includes faucet and receipt waiting, see [examples/typescript/evm/eip7702/createEip7702Delegation.ts](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/evm/eip7702/createEip7702Delegation.ts).

### EVM Smart Accounts

For EVM, we support Smart Accounts which are account-abstraction (ERC-4337) accounts. Currently there is only support for Base Sepolia and Base Mainnet for Smart Accounts.

#### Create an EVM account and a smart account as follows:

```typescript theme={null}
const evmAccount = await cdp.evm.createAccount();
const smartAccount = await cdp.evm.createSmartAccount({
  owner: evmAccount,
});
```

#### Sending User Operations

```typescript theme={null}
const userOperation = await cdp.evm.sendUserOperation({
  smartAccount: smartAccount,
  network: "base-sepolia",
  calls: [
    {
      to: "0x0000000000000000000000000000000000000000",
      value: parseEther("0.000001"),
      data: "0x",
    },
  ],
});
```

#### In Base Sepolia, all user operations are gasless by default. If you'd like to specify a different paymaster, you can do so as follows:

```typescript theme={null}
const userOperation = await cdp.sendUserOperation({
  smartAccount: smartAccount,
  network: "base-sepolia",
  calls: [
    {
      to: "0x0000000000000000000000000000000000000000",
      value: parseEther("0"),
      data: "0x",
    },
  ],
  paymasterUrl: "https://some-paymaster-url.com",
});
```

### EVM Swaps

You can use the CDP SDK to swap tokens on EVM networks using both regular accounts (EOAs) and smart accounts.

The SDK provides three approaches for performing token swaps:

#### 1. All-in-one pattern (Recommended)

The simplest approach for performing swaps. Creates and executes the swap in a single line of code:

**Regular Account (EOA):**

```typescript theme={null}
// Retrieve an existing EVM account with funds already in it
const account = await cdp.evm.getOrCreateAccount({ name: "MyExistingFundedAccount" });

// Execute a swap directly on an EVM account in one line
const { transactionHash } = await account.swap({
  network: "base",
  toToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC on Base
  fromToken: "0x4200000000000000000000000000000000000006", // WETH on Base
  fromAmount: BigInt("1000000000000000000"), // 1 WETH in wei
  slippageBps: 100, // 1% slippage tolerance
});

console.log(`Swap executed: ${transactionHash}`);
```

**Smart Account:**

```typescript theme={null}
// Create or retrieve a smart account with funds already in it
const owner = await cdp.evm.getOrCreateAccount({ name: "MyOwnerAccount" });
const smartAccount = await cdp.evm.getOrCreateSmartAccount({
  name: "MyExistingFundedSmartAccount",
  owner,
});

// Execute a swap directly on a smart account in one line
const { userOpHash } = await smartAccount.swap({
  network: "base",
  toToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC on Base
  fromToken: "0x4200000000000000000000000000000000000006", // WETH on Base
  fromAmount: BigInt("1000000000000000000"), // 1 WETH in wei
  slippageBps: 100, // 1% slippage tolerance
  // Optional: paymasterUrl: "https://paymaster.example.com" // For gas sponsorship
});

console.log(`Smart account swap executed: ${userOpHash}`);

// Wait for the user operation to complete
const receipt = await smartAccount.waitForUserOperation({ userOpHash });
console.log(`Status: ${receipt.status}`);
```

#### 2. Get pricing information

Use `getSwapPrice` for quick price estimates and display purposes. This is ideal for showing exchange rates without committing to a swap:

```typescript theme={null}
const swapPrice = await cdp.evm.getSwapPrice({
  network: "ethereum",
  toToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
  fromToken: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // WETH
  fromAmount: BigInt("1000000000000000000"), // 1 WETH in wei
  taker: "0x1234567890123456789012345678901234567890",
});

if (swapPrice.liquidityAvailable) {
  console.log(`You'll receive: ${swapPrice.toAmount} USDC`);
  console.log(`Minimum after slippage: ${swapPrice.minToAmount} USDC`);
}
```

**Note:** `getSwapPrice` does not reserve funds or signal commitment to swap, making it suitable for more frequent price updates with less strict rate limiting - although the data may be slightly less precise.

#### 3. Create and execute separately

Use `account.quoteSwap()` / `smartAccount.quoteSwap()` when you need full control over the swap process. This returns complete transaction data for execution:

**Important:** `quoteSwap()` signals a soft commitment to swap and may reserve funds on-chain. It is rate-limited more strictly than `getSwapPrice` to prevent abuse.

**Regular Account (EOA):**

```typescript theme={null}
// Retrieve an existing EVM account with funds already in it
const account = await cdp.evm.getOrCreateAccount({ name: "MyExistingFundedAccount" });

// Step 1: Create a swap quote with full transaction details
const swapQuote = await account.quoteSwap({
  network: "base",
  toToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC
  fromToken: "0x4200000000000000000000000000000000000006", // WETH
  fromAmount: BigInt("1000000000000000000"), // 1 WETH in wei
  slippageBps: 100, // 1% slippage tolerance
});

// Step 2: Check if liquidity is available, and/or perform other analysis on the swap quote
if (!swapQuote.liquidityAvailable) {
  console.error("Insufficient liquidity for swap");
  return;
}

// Step 3: Execute using the quote
const { transactionHash } = await swapQuote.execute();
```

**Smart Account:**

```typescript theme={null}
// Create or retrieve a smart account with funds already in it
const owner = await cdp.evm.getOrCreateAccount({ name: "MyOwnerAccount" });
const smartAccount = await cdp.evm.getOrCreateSmartAccount({
  name: "MyExistingFundedSmartAccount",
  owner,
});

// Step 1: Create a swap quote with full transaction details for smart account
const swapQuote = await smartAccount.quoteSwap({
  network: "base",
  toToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC
  fromToken: "0x4200000000000000000000000000000000000006", // WETH
  fromAmount: BigInt("1000000000000000000"), // 1 WETH in wei
  slippageBps: 100, // 1% slippage tolerance
});

// Step 2: Check if liquidity is available, and/or perform other analysis on the swap quote
if (!swapQuote.liquidityAvailable) {
  console.error("Insufficient liquidity for swap");
  return;
}

// Step 3: Execute using the quote
const { userOpHash } = await swapQuote.execute();

// Wait for the user operation to complete
const receipt = await smartAccount.waitForUserOperation({ userOpHash });
console.log(`Status: ${receipt.status}`);
```

#### When to use each approach:

* **All-in-one (`account.swap()` / `smartAccount.swap()`)**: Best for most use cases. Simple, handles everything automatically.
* **Price only (`getSwapPrice`)**: For displaying exchange rates, building price calculators, or checking liquidity without executing. Suitable when frequent price updates are needed - although the data may be slightly less precise.
* **Create then execute (`account.quoteSwap()` / `smartAccount.quoteSwap()`)**: When you need to inspect swap details, implement custom logic, or handle complex scenarios before execution. Note: May reserve funds on-chain and is more strictly rate-limited.

#### Key differences between Regular Accounts (EOAs) and Smart Accounts:

* **Regular accounts (EOAs)** return `transactionHash` and execute immediately on-chain
* **Smart accounts** return `userOpHash` and execute via user operations with optional gas sponsorship through paymasters
* **Smart accounts** require an owner account for signing operations
* **Smart accounts** support batch operations and advanced account abstraction features

All approaches handle Permit2 signatures automatically for ERC20 token swaps. Make sure tokens have proper allowances set for the Permit2 contract before swapping.

#### Example implementations

To help you get started with token swaps in your application, we provide the following fully-working examples demonstrating different scenarios:

**Regular account (EOA) swap examples:**

* [Execute a swap transaction using account (RECOMMENDED)](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/evm/swaps/account.swap.ts) - All-in-one regular account swap execution
* [Quote swap using account convenience method](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/evm/swaps/account.quoteSwap.ts) - Account convenience method for creating quotes
* [Two-step quote and execute process](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/evm/swaps/account.quoteSwapAndExecute.ts) - Detailed two-step approach with analysis
* [Swap with network hoisting](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/evm/swaps/account.swapWithNetworkHoisting.ts) - All-in-one swap and two-step approach swap for EVM chains

**Smart account swap examples:**

* [Execute a swap transaction using smart account (RECOMMENDED)](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/evm/smart-accounts/swap.ts) - All-in-one smart account swap execution with user operations and optional paymaster support
* [Quote swap using smart account convenience method](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/evm/smart-accounts/smartAccount.quoteSwap.ts) - Smart account convenience method for creating quotes
* [Two-step quote and execute process](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/evm/smart-accounts/smartAccount.quoteSwapAndExecute.ts) - Detailed two-step approach with analysis
* [Smart account swap with network hoisting](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/evm/swaps/smartAccount.swapWithNetworkHoisting.ts) - All-in-one smart account swap and two-step approach smart account swap for EVM chains

**BYO wallet (viem) regular account (EOA) swap examples:**

* [Execute a swap transaction using viem account](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/evm/viem.account.swap.ts) - All-in-one swap execution with viem wallets
* [Two-step quote and execute process using viem account](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/evm/viem.account.quoteSwapAndExecute.ts) - Detailed two-step approach with viem wallets

**BYO wallet (viem + account abstraction) smart account swap examples:**

* [Execute a swap transaction using viem smart account](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/evm/viem.smartAccount.swap.ts) - All-in-one smart account swap with custom bundler/paymaster setup
* [Two-step quote and execute process using viem smart account](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/evm/viem.smartAccount.quoteSwapAndExecute.ts) - Advanced account abstraction integration

**Note:** The viem smart account examples require additional dependencies (`permissionless` package) and external service setup (bundler, optional paymaster). For simpler smart account usage, consider CDP's built-in smart account features instead.

### Transferring tokens

#### EVM

For complete examples, check out [evm/account.transfer.ts](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/evm/account.transfer.ts) and [evm/smartAccount.transfer.ts](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/evm/smartAccount.transfer.ts).

You can transfer tokens between accounts using the `transfer` function:

```typescript theme={null}
const sender = await cdp.evm.createAccount({ name: "Sender" });

const { transactionHash } = await sender.transfer({
  to: "0x9F663335Cd6Ad02a37B633602E98866CF944124d",
  amount: 10000n, // equivalent to 0.01 USDC
  token: "usdc",
  network: "base-sepolia",
});
```

You can then [wait for the transaction receipt with a viem Public Client](https://viem.sh/docs/actions/public/waitForTransactionReceipt#waitfortransactionreceipt):

```typescript theme={null}
import { createPublicClient, http } from "viem";
import { baseSepolia } from "viem/chains";

const publicClient = createPublicClient({
  chain: baseSepolia,
  transport: http(),
});

const receipt = await publicClient.waitForTransactionReceipt({ hash: transactionHash });
```

Smart Accounts also have a `transfer` function:

```typescript theme={null}
const sender = await cdp.evm.createSmartAccount({
  owner: privateKeyToAccount(generatePrivateKey()),
});
console.log("Created smart account", sender);

const { userOpHash } = await sender.transfer({
  to: "0x9F663335Cd6Ad02a37B633602E98866CF944124d",
  amount: 10000n, // equivalent to 0.01 USDC
  token: "usdc",
  network: "base-sepolia",
});
```

One difference is that the `transfer` function returns the user operation hash, which is different from the transaction hash. You can use the returned user operation hash in a call to `waitForUserOperation` to get the result of the transaction:

```typescript theme={null}
const receipt = await sender.waitForUserOperation({
  hash: userOpHash,
});

if (receipt.status === "complete") {
  console.log(
    `Transfer successful! Explorer link: https://sepolia.basescan.org/tx/${receipt.userOpHash}`,
  );
} else {
  console.log(`Something went wrong! User operation hash: ${receipt.userOpHash}`);
}
```

Using Smart Accounts, you can also specify a paymaster URL:

```typescript theme={null}
await sender.transfer({
  to: "0x9F663335Cd6Ad02a37B633602E98866CF944124d",
  amount: "0.01",
  token: "usdc",
  network: "base-sepolia",
  paymasterUrl: "https://some-paymaster-url.com",
});
```

Transfer amount must be passed as a bigint. To convert common tokens from whole units, you can use utilities such as [`parseEther`](https://viem.sh/docs/utilities/parseEther#parseether) and [`parseUnits`](https://viem.sh/docs/utilities/parseUnits#parseunits) from viem.

```typescript theme={null}
await sender.transfer({
  to: "0x9F663335Cd6Ad02a37B633602E98866CF944124d",
  amount: parseUnits("0.01", 6), // USDC has 6 decimals
  token: "usdc",
  network: "base-sepolia",
});
```

You can pass `usdc` or `eth` as the token to transfer, or you can pass a contract address directly:

```typescript theme={null}
await sender.transfer({
  to: "0x9F663335Cd6Ad02a37B633602E98866CF944124d",
  amount: parseUnits("0.000001", 18), // WETH has 18 decimals. equivalent to calling `parseEther("0.000001")`
  token: "0x4200000000000000000000000000000000000006", // WETH on Base Sepolia
  network: "base-sepolia",
});
```

You can also pass another account as the `to` parameter:

```typescript theme={null}
const sender = await cdp.evm.createAccount({ name: "Sender" });

const receiver = await cdp.evm.createAccount({ name: "Receiver" });

await sender.transfer({
  to: receiver,
  amount: 10000n, // equivalent to 0.01 USDC
  token: "usdc",
  network: "base-sepolia",
});
```

#### Solana

For complete examples, check out [solana/account.transfer.ts](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/solana/account.transfer.ts).

You can transfer tokens between accounts using the `transfer` function:

```typescript theme={null}
import { createSolanaRpc, type Signature } from "@solana/kit";

const sender = await cdp.solana.createAccount();

const { signature } = await sender.transfer({
  to: "3KzDtddx4i53FBkvCzuDmRbaMozTZoJBb1TToWhz3JfE",
  amount: 10_000_000n, // 0.01 SOL in lamports
  token: "sol",
  network: "devnet",
});

// Poll for confirmation using @solana/kit
const rpc = createSolanaRpc("https://api.devnet.solana.com");
const result = await rpc.getSignatureStatuses([signature as Signature]).send();
const status = result.value[0];

if (status?.err) {
  console.log(`Something went wrong! Error: ${JSON.stringify(status.err)}`);
} else {
  console.log(
    `Transaction confirmed: Link: https://explorer.solana.com/tx/${signature}?cluster=devnet`,
  );
}
```

You can also easily send USDC:

```typescript theme={null}
const { signature } = await sender.transfer({
  to: "3KzDtddx4i53FBkvCzuDmRbaMozTZoJBb1TToWhz3JfE",
  amount: "0.01",
  token: "usdc",
  network: "devnet",
});
```

If you want to use your own RPC client, you can pass one to the `network` parameter:

```typescript theme={null}
import { createSolanaRpc } from "@solana/kit";

const rpc = createSolanaRpc("YOUR_RPC_URL");

const { signature } = await sender.transfer({
  to: "3KzDtddx4i53FBkvCzuDmRbaMozTZoJBb1TToWhz3JfE",
  amount: "0.01",
  token: "usdc",
  network: rpc,
});
```

## Account Actions

Account objects have actions that can be used to interact with the account. These can be used in place of the `cdp` client.

### EVM account actions

Here are some examples for actions on EVM accounts.

For example, instead of:

```typescript theme={null}
const balances = await cdp.evm.listTokenBalances({
  address: account.address,
  network: "base-sepolia",
});
```

You can use the `listTokenBalances` action:

```typescript theme={null}
const account = await cdp.evm.createAccount();
const balances = await account.listTokenBalances({ network: "base-sepolia" });
```

EvmAccount supports the following actions:

* `listTokenBalances`
* `requestFaucet`
* `signTransaction`
* `sendTransaction`
* `transfer`

EvmSmartAccount supports the following actions:

* `listTokenBalances`
* `requestFaucet`
* `sendUserOperation`
* `waitForUserOperation`
* `getUserOperation`
* `transfer`

### Solana account actions

Here are some examples for actions on Solana accounts.

```typescript theme={null}
const balances = await cdp.solana.signMessage({
  address: account.address,
  message: "Hello, world!",
});
```

You can use the `signMessage` action:

```typescript theme={null}
const account = await cdp.solana.createAccount();
const { signature } = await account.signMessage({
  message: "Hello, world!",
});
```

SolanaAccount supports the following actions:

* `requestFaucet`
* `signMessage`
* `signTransaction`

## Policy Management

You can use the policies SDK to manage sets of rules that govern the behavior of accounts and projects, such as enforce allowlists and denylists.

### Create a Project-level policy that applies to all accounts

This policy will accept any account sending less than a specific amount of ETH to a specific address.

```typescript theme={null}
const policy = await cdp.policies.createPolicy({
  policy: {
    scope: "project",
    description: "Project-wide Allowlist Policy",
    rules: [
      {
        action: "accept",
        operation: "signEvmTransaction",
        criteria: [
          {
            type: "ethValue",
            ethValue: "1000000000000000000",
            operator: "<=",
          },
          {
            type: "evmAddress",
            addresses: ["0x000000000000000000000000000000000000dEaD"],
            operator: "in",
          },
        ],
      },
    ],
  },
});
```

### Create an Account-level policy

This policy will accept any transaction with a value less than or equal to 1 ETH to a specific address.

```typescript theme={null}
const policy = await cdp.policies.createPolicy({
  policy: {
    scope: "account",
    description: "Account Allowlist Policy",
    rules: [
      {
        action: "accept",
        operation: "signEvmTransaction",
        criteria: [
          {
            type: "ethValue",
            ethValue: "1000000000000000000",
            operator: "<=",
          },
          {
            type: "evmAddress",
            addresses: ["0x000000000000000000000000000000000000dEaD"],
            operator: "in",
          },
        ],
      },
    ],
  },
});
```

### Create a Solana Allowlist Policy

```typescript theme={null}
const policy = await cdp.policies.createPolicy({
  policy: {
    scope: "account",
    description: "Account Allowlist Policy",
    rules: [
      {
        action: "accept",
        operation: "signSolTransaction",
        criteria: [
          {
            type: "solAddress",
            addresses: ["DtdSSG8ZJRZVv5Jx7K1MeWp7Zxcu19GD5wQRGRpQ9uMF"],
            operator: "in",
          },
        ],
      },
    ],
  },
});
```

### List Policies

You can filter by account:

```typescript theme={null}
const policy = await cdp.policies.listPolicies({
  scope: "account",
});
```

You can also filter by project:

```typescript theme={null}
const policy = await cdp.policies.listPolicies({
  scope: "project",
});
```

### Retrieve a Policy

```typescript theme={null}
const policy = await cdp.policies.getPolicyById({
  id: "__POLICY_ID__",
});
```

### Update a Policy

This policy will update an existing policy to accept transactions to any address except one.

```typescript theme={null}
const policy = await cdp.policies.updatePolicy({
  id: "__POLICY_ID__",
  policy: {
    description: "Updated Account Denylist Policy",
    rules: [
      {
        action: "accept",
        operation: "signEvmTransaction",
        criteria: [
          {
            type: "evmAddress",
            addresses: ["0x000000000000000000000000000000000000dEaD"],
            operator: "not in",
          },
        ],
      },
    ],
  },
});
```

### Delete a Policy

> \[!WARNING] Attempting to delete an account-level policy in-use by at least one account will fail.

```typescript theme={null}
const policy = await cdp.policies.deletePolicy({
  id: "__POLICY_ID__",
});
```

### Validate a Policy

If you're integrating policy editing into your application, you may find it useful to validate policies ahead of time to provide a user with feedback. The `CreatePolicyBodySchema` and `UpdatePolicyBodySchema` can be used to get actionable structured information about any issues with a policy. Read more about [handling ZodErrors](https://zod.dev/ERROR_HANDLING).

```ts theme={null}
import { CreatePolicyBodySchema, UpdatePolicyBodySchema } from "@coinbase/cdp-sdk";

// Validate a new Policy with many issues, will throw a ZodError with actionable validation errors
try {
  CreatePolicyBodySchema.parse({
    description: "Bad description with !#@ characters, also is wayyyyy toooooo long!!",
    rules: [
      {
        action: "acept",
        operation: "unknownOperation",
        criteria: [
          {
            type: "ethValue",
            ethValue: "not a number",
            operator: "<=",
          },
          {
            type: "evmAddress",
            addresses: ["not an address"],
            operator: "in",
          },
          {
            type: "evmAddress",
            addresses: ["not an address"],
            operator: "invalid operator",
          },
        ],
      },
    ],
  });
} catch (e) {
  console.error(e);
}
```

#### Supported Policy Rules

We currently support the following policy rules:

**Server wallet rules:**

* [SignEvmTransactionRule](https://docs.cdp.coinbase.com/api-reference/v2/rest-api/policy-engine/create-a-policy#signevmtransactionrule)
* [SendEvmTransactionRule](https://docs.cdp.coinbase.com/api-reference/v2/rest-api/policy-engine/create-a-policy#sendevmtransactionrule)
* [SignEvmMessageRule](https://docs.cdp.coinbase.com/api-reference/v2/rest-api/policy-engine/create-a-policy#signevmmessagerule)
* [SignEvmTypedDataRule](https://docs.cdp.coinbase.com/api-reference/v2/rest-api/policy-engine/create-a-policy#signevmtypeddatarule)
* [SignSolanaTransactionRule](https://docs.cdp.coinbase.com/api-reference/v2/rest-api/policy-engine/create-a-policy#signsolanatransactionrule)
* [SendSolanaTransactionRule](https://docs.cdp.coinbase.com/api-reference/v2/rest-api/policy-engine/create-a-policy#sendsolanatransactionrule)
* [SignEvmHashRule](https://docs.cdp.coinbase.com/api-reference/v2/rest-api/policy-engine/create-a-policy#signevmhashrule)
* [PrepareUserOperationRule](https://docs.cdp.coinbase.com/api-reference/v2/rest-api/policy-engine/create-a-policy#prepareuseroperationrule)
* [SendUserOperationRule](https://docs.cdp.coinbase.com/api-reference/v2/rest-api/policy-engine/create-a-policy#senduseroperationrule)

**End user rules:**

* `SignEndUserEvmTransactionRule` — operation: `signEndUserEvmTransaction` (criteria: `ethValue`, `evmAddress`, `evmData`, `netUSDChange`)
* `SendEndUserEvmTransactionRule` — operation: `sendEndUserEvmTransaction` (criteria: `ethValue`, `evmAddress`, `evmNetwork`, `evmData`, `netUSDChange`)
* `SignEndUserEvmMessageRule` — operation: `signEndUserEvmMessage` (criteria: `evmMessage`)
* `SignEndUserEvmTypedDataRule` — operation: `signEndUserEvmTypedData` (criteria: `evmTypedDataField`, `evmTypedDataVerifyingContract`)
* `SignEndUserSolTransactionRule` — operation: `signEndUserSolTransaction` (criteria: `solAddress`, `solValue`, `splAddress`, `splValue`, `mintAddress`, `solData`, `programId`)
* `SendEndUserSolTransactionRule` — operation: `sendEndUserSolTransaction` (criteria: `solAddress`, `solValue`, `splAddress`, `splValue`, `mintAddress`, `solData`, `programId`, `solNetwork`)
* `SignEndUserSolMessageRule` — operation: `signEndUserSolMessage` (criteria: `solMessage`)

End user rules use the same criteria types as their server wallet counterparts. For example, `signEndUserEvmTransaction` supports the same `ethValue`, `evmAddress`, and `evmData` criteria as `signEvmTransaction`.

### End User Policies

You can create policies that govern end-user operations using the same criteria types available for server wallet policies. The only difference is the `operation` value, which targets end-user-specific actions.

#### End User EVM Policy

This policy restricts end-user EVM transaction signing to a max value and allowlisted recipients — the same criteria used in `signEvmTransaction`:

```typescript theme={null}
const policy = await cdp.policies.createPolicy({
  policy: {
    scope: "project",
    description: "End User EVM Policy",
    rules: [
      {
        action: "accept",
        operation: "signEndUserEvmTransaction",
        criteria: [
          {
            type: "ethValue",
            ethValue: "1000000000000000000", // 1 ETH in wei
            operator: "<=",
          },
          {
            type: "evmAddress",
            addresses: ["0x000000000000000000000000000000000000dEaD"],
            operator: "in",
          },
        ],
      },
    ],
  },
});
```

#### End User Solana Policy

This policy restricts end-user Solana transaction signing to allowlisted recipients under a SOL value threshold — the same criteria used in `signSolTransaction`:

```typescript theme={null}
const policy = await cdp.policies.createPolicy({
  policy: {
    scope: "project",
    description: "End User Solana Policy",
    rules: [
      {
        action: "accept",
        operation: "signEndUserSolTransaction",
        criteria: [
          {
            type: "solAddress",
            addresses: ["11111111111111111111111111111111"],
            operator: "in",
          },
          {
            type: "solValue",
            solValue: "1000000000", // 1 SOL in lamports
            operator: "<=",
          },
        ],
      },
    ],
  },
});
```

> For a comprehensive example demonstrating all 7 end-user operations, see [createEndUserPolicy.ts](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/end-users/createEndUserPolicy.ts).

### End-user Management

You can use the End User SDK to manage the users of your applications.

#### Create End User

You can create an end user with authentication methods and optionally create EVM and Solana accounts for them.

```typescript theme={null}
const endUser = await cdp.endUser.createEndUser({
  authenticationMethods: [{ type: "email", email: "user@example.com" }],
  evmAccount: { createSmartAccount: true },
  solanaAccount: { createSmartAccount: false },
});

console.log(endUser);
```

#### Import End User

You can import an existing private key for an end user:

```typescript theme={null}
const endUser = await cdp.endUser.importEndUser({
  authenticationMethods: [{ type: "email", email: "user@example.com" }],
  privateKey: "0x...", // EVM private key (hex string)
  keyType: "evm",
});

console.log(endUser);
```

You can also import a Solana private key:

```typescript theme={null}
const endUser = await cdp.endUser.importEndUser({
  authenticationMethods: [{ type: "email", email: "user@example.com" }],
  privateKey: "3Kzj...", // base58 encoded
  keyType: "solana",
});

console.log(endUser);
```

#### Add EVM Account to End User

Add an additional EVM EOA (Externally Owned Account) to an existing end user. You can call the method directly on the EndUser object:

```typescript theme={null}
// Using the EndUser object method (recommended)
const result = await endUser.addEvmAccount();
console.log(`Added EVM account: ${result.evmAccount.address}`);

// Or using the client method
const result = await cdp.endUser.addEndUserEvmAccount({
  userId: endUser.userId,
});
console.log(`Added EVM account: ${result.evmAccount.address}`);
```

#### Add EVM Smart Account to End User

Add an EVM smart account to an existing end user:

```typescript theme={null}
// Using the EndUser object method (recommended)
const result = await endUser.addEvmSmartAccount({ enableSpendPermissions: true });
console.log(`Added EVM smart account: ${result.evmSmartAccount.address}`);

// Or using the client method
const result = await cdp.endUser.addEndUserEvmSmartAccount({
  userId: endUser.userId,
  enableSpendPermissions: true,
});
console.log(`Added EVM smart account: ${result.evmSmartAccount.address}`);
```

#### Add Solana Account to End User

Add an additional Solana account to an existing end user:

```typescript theme={null}
// Using the EndUser object method (recommended)
const result = await endUser.addSolanaAccount();
console.log(`Added Solana account: ${result.solanaAccount.address}`);

// Or using the client method
const result = await cdp.endUser.addEndUserSolanaAccount({
  userId: endUser.userId,
});
console.log(`Added Solana account: ${result.solanaAccount.address}`);
```

#### Validate Access Token

When your end user has signed in with an [Embedded Wallet](https://docs.cdp.coinbase.com/embedded-wallets/welcome), you can check whether the access token they were granted is valid, and which of your user's it is associated with.

```typescript theme={null}
try {
  const endUser = await cdp.endUser.validateAccessToken({
    accessToken,
  });
  console.log(endUser);
} catch (e) {
  // the access token is not valid or expired
}
```

## Delegated Signing Operations

When an end user has granted a delegation, you can sign and send transactions on their behalf using the `cdp.endUser` client methods or directly on the `EndUserAccount` object.

All delegated operations are available both as client methods (passing `userId` explicitly) and as convenience methods on the `EndUserAccount` object (where `userId` is automatically bound and `address` defaults to the first account if not specified).

### Revoke Delegation

Revoke all active delegations for an end user:

```typescript theme={null}
// Using the client method
await cdp.endUser.revokeDelegationForEndUser({
  userId: "user-123",
});

// Or using the EndUser object
const endUser = await cdp.endUser.getEndUser({ userId: "user-123" });
await endUser.revokeDelegation();
```

For a complete example, see [end-users/revokeDelegation.ts](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/end-users/revokeDelegation.ts).

### EVM Signing

#### Sign an EVM Transaction

```typescript theme={null}
const result = await cdp.endUser.signEvmTransaction({
  userId: "user-123",
  address: "0x1234...",
  transaction: "0x02...", // RLP-serialized EIP-1559 transaction, hex-encoded
});
console.log(result.signedTransaction);

// Or using the EndUser object
const result = await endUser.signEvmTransaction({
  transaction: "0x02...",
});
console.log(result.signedTransaction);
```

#### Sign an EVM Message (EIP-191)

```typescript theme={null}
const result = await cdp.endUser.signEvmMessage({
  userId: "user-123",
  address: "0x1234...",
  message: "Hello, World!",
});
console.log(result.signature);

// Or using the EndUser object
const result = await endUser.signEvmMessage({
  message: "Hello, World!",
});
console.log(result.signature);
```

#### Sign EVM Typed Data (EIP-712)

```typescript theme={null}
const result = await cdp.endUser.signEvmTypedData({
  userId: "user-123",
  address: "0x1234...",
  typedData: {
    domain: { name: "Example" },
    types: { Message: [{ name: "content", type: "string" }] },
    primaryType: "Message",
    message: { content: "Hello" },
  },
});
console.log(result.signature);

// Or using the EndUser object
const result = await endUser.signEvmTypedData({
  typedData: {
    domain: { name: "Example" },
    types: { Message: [{ name: "content", type: "string" }] },
    primaryType: "Message",
    message: { content: "Hello" },
  },
});
console.log(result.signature);
```

### EVM Sending

#### Send an EVM Transaction

```typescript theme={null}
const result = await cdp.endUser.sendEvmTransaction({
  userId: "user-123",
  address: "0x1234...",
  transaction: "0x02...", // RLP-serialized EIP-1559 transaction, hex-encoded
  network: "base-sepolia",
});
console.log(result.transactionHash);

// Or using the EndUser object
const result = await endUser.sendEvmTransaction({
  transaction: "0x02...",
  network: "base-sepolia",
});
console.log(result.transactionHash);
```

For a complete example, see [end-users/sendEvmTransaction.ts](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/end-users/sendEvmTransaction.ts).

#### Send an EVM Asset

Send tokens (e.g. USDC) on behalf of an end user:

```typescript theme={null}
const result = await cdp.endUser.sendEvmAsset({
  userId: "user-123",
  address: "0x1234...",
  to: "0xabcd...",
  amount: "1000000",
  network: "base-sepolia",
  asset: "usdc", // optional, defaults to "usdc"
  useCdpPaymaster: true, // optional
});
console.log(result.transactionHash);

// Or using the EndUser object
const result = await endUser.sendEvmAsset({
  to: "0xabcd...",
  amount: "1000000",
  network: "base-sepolia",
});
console.log(result.transactionHash);
```

For a complete example, see [end-users/sendEvmAsset.ts](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/end-users/sendEvmAsset.ts).

#### Send a User Operation (Smart Account)

Send a user operation via an end user's smart account:

```typescript theme={null}
const result = await cdp.endUser.sendUserOperation({
  userId: "user-123",
  address: "0x1234...", // smart account address
  network: "base-sepolia",
  calls: [
    {
      to: "0xabcd...",
      value: "0",
      data: "0x",
    },
  ],
  useCdpPaymaster: true,
});

// Or using the EndUser object (address defaults to the first smart account)
const result = await endUser.sendUserOperation({
  network: "base-sepolia",
  calls: [
    {
      to: "0xabcd...",
      value: "0",
      data: "0x",
    },
  ],
  useCdpPaymaster: true,
});
```

For a complete example, see [end-users/sendUserOperation.ts](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/end-users/sendUserOperation.ts).

### EVM EIP-7702 Delegation

Create an EIP-7702 delegation on behalf of an end user, upgrading their EOA with smart account capabilities:

```typescript theme={null}
const result = await cdp.endUser.createEvmEip7702Delegation({
  userId: "user-123",
  address: "0x1234...",
  network: "base-sepolia",
  enableSpendPermissions: false, // optional
});
console.log(result.delegationOperationId);

// Or using the EndUser object
const result = await endUser.createEvmEip7702Delegation({
  network: "base-sepolia",
});
console.log(result.delegationOperationId);
```

For a complete example, see [end-users/createEvmEip7702Delegation.ts](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/end-users/createEvmEip7702Delegation.ts).

### Solana Signing

#### Sign a Solana Message

```typescript theme={null}
const result = await cdp.endUser.signSolanaMessage({
  userId: "user-123",
  address: "So1ana...",
  message: "base64message...",
});
console.log(result.signature);

// Or using the EndUser object
const result = await endUser.signSolanaMessage({
  message: "base64message...",
});
console.log(result.signature);
```

For a complete example, see [end-users/signSolanaMessage.ts](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/end-users/signSolanaMessage.ts).

#### Sign a Solana Transaction

```typescript theme={null}
const result = await cdp.endUser.signSolanaTransaction({
  userId: "user-123",
  address: "So1ana...",
  transaction: "base64tx...",
});
console.log(result.signedTransaction);

// Or using the EndUser object
const result = await endUser.signSolanaTransaction({
  transaction: "base64tx...",
});
console.log(result.signedTransaction);
```

### Solana Sending

#### Send a Solana Transaction

```typescript theme={null}
const result = await cdp.endUser.sendSolanaTransaction({
  userId: "user-123",
  address: "So1ana...",
  transaction: "base64tx...",
  network: "solana-devnet",
});
console.log(result.transactionSignature);

// Or using the EndUser object
const result = await endUser.sendSolanaTransaction({
  transaction: "base64tx...",
  network: "solana-devnet",
});
console.log(result.transactionSignature);
```

#### Send a Solana Asset

```typescript theme={null}
const result = await cdp.endUser.sendSolanaAsset({
  userId: "user-123",
  address: "So1ana...",
  to: "Recipi...",
  amount: "1000000",
  network: "solana-devnet",
  asset: "usdc", // optional, defaults to "usdc"
  createRecipientAta: true, // optional, creates recipient's associated token account
});
console.log(result.transactionSignature);

// Or using the EndUser object
const result = await endUser.sendSolanaAsset({
  to: "Recipi...",
  amount: "1000000",
  network: "solana-devnet",
});
console.log(result.transactionSignature);
```

## x402 Payment Protocol

[x402](https://x402.org) is an open payment protocol that lets clients pay for HTTP requests using the `402 Payment Required` status code. The SDK ships x402 support in the `@coinbase/cdp-sdk/x402` subpath, which builds on top of the [`@x402`](https://www.npmjs.com/org/x402) packages:

* **Payment client** (`CdpX402Client`) — pay for x402-protected APIs with a CDP-managed wallet
* **Spend controls** — SDK-managed guardrails (per-payment caps, cumulative caps, allowlists) for autonomous agents
* **Resource server** (`createX402Server`) — add x402 payment gating to your HTTP endpoints
* **Facilitator** (`createCdpFacilitatorClient`) — the CDP-hosted payment facilitator for verifying and settling payments
* **Signer adapters** (`fromCdpEvmAccount`, `fromCdpSmartWallet`, `cdpSolanaAccountToSvmSigner`) — bridge CDP accounts into an existing `@x402` setup
* **Direct signing** (`signX402Payment`) — sign a payment payload with a CDP account without an HTTP round-trip

All entry points resolve `CDP_API_KEY_ID`, `CDP_API_KEY_SECRET`, and (where a wallet is required) `CDP_WALLET_SECRET` from environment variables, and accept explicit overrides via config. See the [x402 examples](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/x402) for complete, runnable programs.

`@x402/core`, `@x402/evm`, `@x402/extensions`, and `@x402/svm` are optional peer dependencies — install the ones you need alongside `@coinbase/cdp-sdk` (e.g. `npm install @x402/core @x402/evm @x402/svm`) rather than expecting them to come along automatically. `@x402/fetch` isn't used by the SDK itself, but pairs well with `CdpX402Client` if you want its `wrapFetchWithPayment` helper — install it separately if so.

### Pay for an x402-protected API

`CdpX402Client` extends `@x402/core`'s `x402Client` and auto-provisions a CDP-managed wallet on the first payment. Pass it to `wrapFetchWithPayment` from `@x402/fetch` to transparently pay for `402`-gated requests.

```typescript theme={null}
import { CdpX402Client } from "@coinbase/cdp-sdk/x402";
import { wrapFetchWithPayment } from "@x402/fetch";

// Set CDP_API_KEY_ID, CDP_API_KEY_SECRET, CDP_WALLET_SECRET in your environment.
const client = new CdpX402Client();
const fetchWithPayment = wrapFetchWithPayment(fetch, client);

const response = await fetchWithPayment("https://api.example.com/report");
```

The wallet used for payment is managed internally (a CDP Server Wallet named `"x402-client-wallet-1"` by default). To find its address — for example, to fund it before paying — call `getAddresses()`, which provisions the wallet eagerly instead of waiting for the first payment:

```typescript theme={null}
const client = new CdpX402Client();
const { evmAddress, svmAddress } = await client.getAddresses();
console.log("Fund this address before paying:", evmAddress, svmAddress);
```

By default the client uses a CDP Server Wallet (EOA). To pay from a CDP Smart Account instead, supply a `walletConfig`:

```typescript theme={null}
const client = new CdpX402Client({
  walletConfig: {
    type: "smart",
    accountName: "my-smart-wallet",
    ownerAccountName: "my-owner",
  },
});
```

### Apply spend controls

Attach `spendControls` to `CdpX402Client` to enforce per-payment and cumulative caps, restrict networks/assets/payees, and receive callbacks as spend approaches a limit. A blocked payment throws a `SpendControlError` with a machine-readable `code`.

```typescript theme={null}
import { CdpX402Client, SpendControlError } from "@coinbase/cdp-sdk/x402";

const USDC_BASE = "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913";

const client = new CdpX402Client({
  spendControls: {
    maxAmountPerPayment: { atomic: 10_000n, asset: USDC_BASE },
    maxCumulativeSpend: { atomic: 50_000n, asset: USDC_BASE },
    maxCumulativeSpendWindow: "24h",
    allowedNetworks: ["eip155:8453"],
    onApproachingLimit: (spent, limit) => {
      const pct = (Number(spent.atomic) / Number(limit.atomic)) * 100;
      console.warn(`Approaching spend limit: ${pct.toFixed(0)}% of cap used`);
    },
  },
});
```

Spend controls can also be applied to any `@x402/core` client directly via `applySpendControls(client, controls)`. Provide a persistent `SpendStore` (via the `store` option) if you need the cumulative ledger to survive process restarts — the default store is in-memory.

### Gate an HTTP endpoint

`createX402Server` provisions a receiver wallet and returns a server descriptor you can hand to an `@x402` HTTP middleware (for example `@x402/express`).

```typescript theme={null}
import { createX402Server } from "@coinbase/cdp-sdk/x402";
import { paymentMiddlewareFromHTTPServer } from "@x402/express";

// Set CDP_API_KEY_ID, CDP_API_KEY_SECRET, CDP_WALLET_SECRET in your environment.
const server = await createX402Server({
  routes: { "GET /report": { price: "$0.01", description: "AI-generated report" } },
});

app.use(paymentMiddlewareFromHTTPServer(server));
console.log("Receiving EVM payments at", server.payToEvmAddress);
```

### Use the CDP-hosted facilitator

`createCdpFacilitatorClient` returns a CDP-authenticated `HTTPFacilitatorClient` that verifies and settles payments through the CDP-hosted facilitator. It is a drop-in replacement for a self-hosted facilitator and only needs API-key credentials (no wallet secret).

```typescript theme={null}
import { createCdpFacilitatorClient } from "@coinbase/cdp-sdk/x402";
import { x402ResourceServer } from "@x402/core/server";
import { ExactEvmScheme } from "@x402/evm/exact/server";

// Set CDP_API_KEY_ID and CDP_API_KEY_SECRET in your environment.
const facilitator = createCdpFacilitatorClient();

const server = new x402ResourceServer(facilitator).register("eip155:8453", new ExactEvmScheme());
```

### Use a CDP wallet with an existing x402 client

If you already have an `@x402` client set up, use the signer adapters to sign with a CDP-managed account instead of a local private key.

```typescript theme={null}
import { CdpClient } from "@coinbase/cdp-sdk";
import { fromCdpEvmAccount } from "@coinbase/cdp-sdk/x402";
import { x402Client } from "@x402/core/client";
import { registerExactEvmScheme } from "@x402/evm/exact/client";

const cdp = new CdpClient();
const account = await cdp.evm.getOrCreateAccount({ name: "my-signer" });

const client = new x402Client();
registerExactEvmScheme(client, { signer: fromCdpEvmAccount(account) });
```

Use `fromCdpSmartWallet` for a CDP Smart Account and `cdpSolanaAccountToSvmSigner` for a CDP Solana account.

### Sign an x402 payment payload directly

CDP accounts can also sign x402 payment payloads directly. Direct signing is useful when the payment payload needs to travel over non-HTTP transports such as gRPC metadata, MCP tool results, queues, or batch jobs.

Use `signX402Payment(paymentRequired, acceptedIndex)` on any CDP-managed EVM account, EVM smart account, or Solana account. `paymentRequired` is the x402 payment requirement object returned by a resource server. `acceptedIndex` selects which entry in `paymentRequired.accepts` to sign.

```typescript theme={null}
import { CdpClient } from "@coinbase/cdp-sdk";

const cdp = new CdpClient();
const account = await cdp.evm.getOrCreateAccount({ name: "agent" });

const acceptedIndex = 0;
const payment = await account.signX402Payment(paymentRequired, acceptedIndex);

// gRPC metadata example
metadata.set("x402-payment", Buffer.from(JSON.stringify(payment)).toString("base64"));

// MCP tool result example
return {
  content: [{ type: "text", text: "paid result" }],
  _meta: { x402Payment: payment },
};

// Queue or batch job example
await queue.publish("paid-job", { payment, jobId });
```

For smart accounts (supports the EIP-3009 `exact` flow only — smart accounts sign with an ERC-1271/ERC-6492 contract signature, so the Permit2-based `upto` scheme and `exact` requirements that use the Permit2 transfer method are not supported):

```typescript theme={null}
const owner = await cdp.evm.getOrCreateAccount({ name: "agent-owner" });
const smartAccount = await cdp.evm.getOrCreateSmartAccount({
  name: "agent-smart-account",
  owner,
});

const acceptedIndex = 0;
const payment = await smartAccount.signX402Payment(paymentRequired, acceptedIndex);
```

For Solana accounts, the same surface produces an exact SVM payment payload:

```typescript theme={null}
const solanaAccount = await cdp.solana.getOrCreateAccount({ name: "solana-agent" });
const acceptedIndex = 0;
const payment = await solanaAccount.signX402Payment(paymentRequired, acceptedIndex);
```

## Webhooks

You can use the webhooks SDK to subscribe to on-chain and wallet events and receive notifications at a URL of your choice.

### Create Subscription

Create a webhook subscription to receive event notifications:

```typescript theme={null}
const subscription = await cdp.webhooks.createSubscription({
  description: "Monitor wallet transactions",
  eventTypes: [
    "wallet.transaction.pending",
    "wallet.transaction.confirmed",
    "wallet.transaction.failed",
  ],
  targetUrl: "https://example.com/webhook",
  targetHeaders: { "X-Custom-Header": "custom-value" }, // optional
  isEnabled: true, // optional, defaults to true
  metadata: { env: "production" }, // optional
});

console.log("Subscription ID:", subscription.subscriptionId);
console.log("Secret:", subscription.secret); // use to verify webhook signatures
```

The available wallet event types are:

* `wallet.transaction.created`
* `wallet.transaction.broadcast`
* `wallet.transaction.pending`
* `wallet.transaction.replaced`
* `wallet.transaction.confirmed`
* `wallet.transaction.failed`
* `wallet.transaction.signed`
* `wallet.typed_data.signed`
* `wallet.message.signed`
* `wallet.hash.signed`
* `wallet.delegation.created`
* `wallet.delegation.revoked`

For a complete working example, see [webhooks/createWebhookSubscription.ts](https://github.com/coinbase/cdp-sdk/blob/main/examples/typescript/webhooks/createWebhookSubscription.ts).

## Authentication tools

This SDK also contains simple tools for authenticating REST API requests to the [Coinbase Developer Platform (CDP)](https://docs.cdp.coinbase.com/). See the [Auth README](/sdks/cdp-sdks-v2/typescript/auth) for more details.

## Error Reporting

This SDK contains error reporting functionality that sends error events to CDP. If you would like to disable this behavior, you can set the `DISABLE_CDP_ERROR_REPORTING` environment variable to `true`.

```bash theme={null}
DISABLE_CDP_ERROR_REPORTING=true
```

## Usage Tracking

This SDK contains usage tracking functionality that sends usage events to CDP. If you would like to disable this behavior, you can set the `DISABLE_CDP_USAGE_TRACKING` environment variable to `true`.

## License

This project is licensed under the MIT License - see the [LICENSE](https://github.com/coinbase/cdp-sdk/tree/main/LICENSE) file for details.

## Support

For feature requests, feedback, or questions, please reach out to us in the **#cdp-sdk** channel of the [Coinbase Developer Platform Discord](https://discord.com/invite/cdp).

* [SDK Docs](https://docs.cdp.coinbase.com/sdks/cdp-sdks-v2/typescript)
* [GitHub Issues](https://github.com/coinbase/cdp-sdk/issues)

## Security

If you discover a security vulnerability within this SDK, please see our [Security Policy](https://github.com/coinbase/cdp-sdk/tree/main/SECURITY) for disclosure information.

## FAQ

Common errors and their solutions.

### TypeScript compilation errors with `generateJwt` or `moduleResolution`

If you encounter TypeScript compilation errors when using the CDP SDK, particularly with `generateJwt` or import statements, you may need to update your TypeScript configuration.

**Error symptoms:**

* Type errors with `generateJwt` function
* Module resolution errors
* Import/export type mismatches

**Solution:**

Update your `tsconfig.json` to use a modern module resolution strategy. Change `moduleResolution` from `node` to `node16` or `nodenext`:

```json theme={null}
{
  "compilerOptions": {
    "moduleResolution": "node16" // or "nodenext"
    // ... other options
  }
}
```

The CDP SDK is built as an ESM package and `moduleResolution: "node16"` or `"nodenext"` should be used for proper type resolution. The legacy `"node"` setting doesn't correctly resolve ESM package exports.

### AggregateError \[ETIMEDOUT]

This is an issue in Node.js itself: [https://github.com/nodejs/node/issues/54359](https://github.com/nodejs/node/issues/54359). While [the fix](https://github.com/nodejs/node/pull/56738) is implemented, the workaround is to set the environment variable:

```bash theme={null}
export NODE_OPTIONS="--network-family-autoselection-attempt-timeout=500"
```

### Error \[ERR\_REQUIRE\_ESM]: require() of ES modules is not supported.

Use Node v20.19.0 or higher. CDP SDK depends on [jose](https://github.com/panva/jose) v6, which ships only ESM. Jose supports CJS style imports in Node.js versions where the require(esm) feature is enabled by default (^20.19.0 || ^22.12.0 || >= 23.0.0). [See here for more info](https://github.com/panva/jose?tab=readme-ov-file#user-content-fn-cjs-705c79d785ca9bc0f9ec1e8ce0825c74).

### Jest encountered an unexpected token

If you're using Jest and see an error like this:

```
Details:

/Users/.../node_modules/jose/dist/webapi/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export { compactDecrypt } from './jwe/compact/decrypt.js';
                                                                                  ^^^^^^

SyntaxError: Unexpected token 'export'
```

Add a file called `jest.setup.ts` next to your `jest.config` file with the following content:

```typescript theme={null}
jest.mock("jose", () => {});
```

Then, add the following line to your `jest.config` file:

```typescript theme={null}
setupFilesAfterEnv: ["<rootDir>/jest.setup.ts"],
```

x402 support for the CDP SDK.

Import from `@coinbase/cdp-sdk/x402` to access:

* **Resource server**: `createX402Server` — add x402 payment gating to HTTP endpoints
* **Payment client**: `CdpX402Client` — pay for x402-protected APIs
* **Facilitator**: `createCdpFacilitatorClient` — CDP-hosted payment facilitator
* **Spend controls**: guardrails for autonomous agents
* **Signer adapters**: bridge CDP accounts into existing x402 setups

## Quick start

### Gate an endpoint

```typescript theme={null}
import { createX402Server } from "@coinbase/cdp-sdk/x402";
import { paymentMiddlewareFromHTTPServer } from "@x402/express";

// Set: CDP_API_KEY_ID, CDP_API_KEY_SECRET, CDP_WALLET_SECRET
const server = await createX402Server({
  routes: { "GET /report": { price: "$0.01", description: "AI-generated report" } },
});
app.use(paymentMiddlewareFromHTTPServer(server));
console.log("Receiving EVM payments at", server.payToEvmAddress);
```

### Pay for an x402-protected API

```typescript theme={null}
import { CdpX402Client } from "@coinbase/cdp-sdk/x402";
import { wrapFetchWithPayment } from "@x402/fetch";

// Set: CDP_API_KEY_ID, CDP_API_KEY_SECRET, CDP_WALLET_SECRET
const client = new CdpX402Client();
const fetchWithPayment = wrapFetchWithPayment(fetch, client);
const response = await fetchWithPayment("https://api.example.com/report");
```

### Use a CDP-managed wallet with an existing x402Client

```typescript theme={null}
import { CdpClient } from "@coinbase/cdp-sdk";
import { x402Client } from "@x402/core/client";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { fromCdpEvmAccount } from "@coinbase/cdp-sdk/x402";

const cdp = new CdpClient();
const account = await cdp.evm.getOrCreateAccount({ name: "my-signer" });

const client = new x402Client();
registerExactEvmScheme(client, { signer: fromCdpEvmAccount(account) });
```

## Classes

* [X402Server](/sdks/cdp-sdks-v2/typescript/x402/classes/X402Server)
* [CdpX402Client](/sdks/cdp-sdks-v2/typescript/x402/classes/CdpX402Client)
* [SpendControlError](/sdks/cdp-sdks-v2/typescript/x402/classes/SpendControlError)
* [SpendTracker](/sdks/cdp-sdks-v2/typescript/x402/classes/SpendTracker)

## Interfaces

### CdpX402ServerConfig

Defined in: [server.ts:264](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/server.ts#L264)

Configuration for `createX402Server()`.

All credential fields fall back to environment variables, so an empty
object `{}` with a `routes` map is sufficient in most environments.

Pass `configPath` to load routes (and optionally credentials) from a JSON
file instead of specifying them inline.

#### Properties

##### apiKeyId?

```ts theme={null}
optional apiKeyId: string;
```

Defined in: [server.ts:269](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/server.ts#L269)

CDP API key ID.
Falls back to `CDP_API_KEY_ID` env var.

##### apiKeySecret?

```ts theme={null}
optional apiKeySecret: string;
```

Defined in: [server.ts:274](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/server.ts#L274)

CDP API key secret.
Falls back to `CDP_API_KEY_SECRET` env var.

##### walletSecret?

```ts theme={null}
optional walletSecret: string;
```

Defined in: [server.ts:280](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/server.ts#L280)

CDP wallet secret used to provision the receiver wallet.
Falls back to `CDP_WALLET_SECRET` env var.
Not required when `payToConfig.type` is `"address"`.

##### environment?

```ts theme={null}
optional environment: "production" | "development";
```

Defined in: [server.ts:289](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/server.ts#L289)

Deployment environment. Controls which networks are used by default.

* `"production"` (default) — Base mainnet + Solana mainnet.
* `"development"` — Base Sepolia + Solana Devnet.

Falls back to `CDP_X402_SERVER_ENVIRONMENT` env var.

##### payToConfig?

```ts theme={null}
optional payToConfig: PayToConfig;
```

Defined in: [server.ts:299](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/server.ts#L299)

Receiver wallet / payTo configuration.

Defaults to `{ type: "eoa" }` which provisions a CDP Server Wallet (EOA)
named `"x402-receiver-wallet-1"`.

Use `{ type: "address", evm: "0x...", solana: "..." }` to provide your
own addresses without provisioning a CDP wallet.

##### routes?

```ts theme={null}
optional routes: Record<string, 
  | RouteConfig
| CdpRouteConfig>;
```

Defined in: [server.ts:313](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/server.ts#L313)

Payment-protected routes served by this server.

Map of HTTP method + path pattern → route config.
Keys use the `"METHOD /path"` convention, e.g. `"GET /report"`.

Each value is either:

* A `CdpRouteConfig` — simplified format, just `price` + optional fields.
* A `RouteConfig` — full x402 format with an `accepts` array/object.

Both formats can be mixed within the same map.
May be omitted when `configPath` supplies the routes.

##### configPath?

```ts theme={null}
optional configPath: string;
```

Defined in: [server.ts:335](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/server.ts#L335)

Path to a JSON file whose fields are merged with this inline config.
Inline config takes precedence over file config when both specify the
same field. The file mirrors [CdpX402ServerConfig](/sdks/cdp-sdks-v2/typescript/x402/index#cdpx402serverconfig) (minus `configPath`).

###### Example

```json theme={null}
{
  "routes": {
    "GET /report": { "price": "$0.01", "description": "AI-generated report" }
  }
}
```

A full JSON Schema for the file lives at
`examples/typescript/x402/servers/express/x402.config.schema.json`.

Security: this file may carry credentials (`apiKeySecret` / `walletSecret`).
Prefer environment variables for credentials and use the file for `routes`;
if secrets are stored here, keep the file out of version control.

***

### CdpRouteConfig

Defined in: [server.ts:169](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/server.ts#L169)

Simplified CDP-owned route configuration.

Specifying just `price` (and optionally `description` / `networks`) is
enough for most routes. `createX402Server` automatically expands this
into the full x402 `RouteConfig` format with `scheme`, `payTo`, and
`maxTimeoutSeconds` filled in.

For routes that need fine-grained control (custom scheme, explicit `payTo`,
etc.) pass a full x402 `RouteConfig` instead — both formats are accepted
in the same `routes` map.

#### Properties

##### price

```ts theme={null}
price: string;
```

Defined in: [server.ts:174](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/server.ts#L174)

Payment amount required to access this route, e.g. `"$0.01"`.
Accepts any amount string supported by the x402 protocol.

##### description?

```ts theme={null}
optional description: string;
```

Defined in: [server.ts:176](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/server.ts#L176)

Human-readable description of what this route provides.

##### scheme?

```ts theme={null}
optional scheme: CdpPaymentScheme;
```

Defined in: [server.ts:186](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/server.ts#L186)

Payment scheme to use for this route.

Defaults to `"exact"`. The `"upto"` and `"batch-settlement"` schemes are
EVM-only — `networks` must not include Solana or other non-EVM chains when
they are specified. When an EVM-only scheme is used without an explicit
`networks` list the default falls back to the environment's EVM networks
(Base mainnet or Base Sepolia depending on `environment`).

##### networks?

```ts theme={null}
optional networks: string[];
```

Defined in: [server.ts:193](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/server.ts#L193)

CAIP-2 network identifiers for which the route accepts payments.
Defaults to `CDP_SERVER_DEFAULT_NETWORKS` (Base mainnet + Solana mainnet)
for the `"exact"` scheme, or `CDP_SERVER_DEFAULT_EVM_NETWORKS` (Base
mainnet only) for `"upto"`.

##### maxTimeoutSeconds?

```ts theme={null}
optional maxTimeoutSeconds: number;
```

Defined in: [server.ts:198](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/server.ts#L198)

Maximum seconds a payment token is valid before expiry.
Defaults to `300` (5 minutes).

##### extensions?

```ts theme={null}
optional extensions: Record<string, unknown>;
```

Defined in: [server.ts:206](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/server.ts#L206)

Extension overrides for this route.

All three CDP extensions (`eip2612GasSponsoring`, `erc20ApprovalGasSponsoring`,
and `bazaar`) are injected automatically. Use this field to override the
auto-generated Bazaar declaration with richer discovery metadata.

***

### CdpSchemeRegistration

Defined in: [server-extensions.ts:161](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/server-extensions.ts#L161)

A scheme+network pair used to register payment schemes on an `x402ResourceServer`.

#### Properties

##### network

```ts theme={null}
network: `${string}:${string}`;
```

Defined in: [server-extensions.ts:163](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/server-extensions.ts#L163)

CAIP-2 network identifier, e.g. `"eip155:*"` or `"solana:*"`.

##### server

```ts theme={null}
server: SchemeNetworkServer;
```

Defined in: [server-extensions.ts:165](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/server-extensions.ts#L165)

Scheme server implementation for this network.

***

### CdpX402ClientConfig

Defined in: [client.ts:60](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/client.ts#L60)

Configuration for [CdpX402Client](/sdks/cdp-sdks-v2/typescript/x402/classes/CdpX402Client).

#### Properties

##### apiKeyId?

```ts theme={null}
optional apiKeyId: string;
```

Defined in: [client.ts:62](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/client.ts#L62)

CDP API key ID. Falls back to `CDP_API_KEY_ID` env var.

##### apiKeySecret?

```ts theme={null}
optional apiKeySecret: string;
```

Defined in: [client.ts:64](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/client.ts#L64)

CDP API key secret. Falls back to `CDP_API_KEY_SECRET` env var.

##### walletSecret?

```ts theme={null}
optional walletSecret: string;
```

Defined in: [client.ts:66](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/client.ts#L66)

CDP wallet secret. Falls back to `CDP_WALLET_SECRET` env var.

##### walletConfig?

```ts theme={null}
optional walletConfig: WalletConfig;
```

Defined in: [client.ts:70](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/client.ts#L70)

Wallet configuration. Defaults to `{ type: "eoa" }`.

##### spendControls?

```ts theme={null}
optional spendControls: SpendControls;
```

Defined in: [client.ts:74](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/client.ts#L74)

Optional SDK-managed spend controls.

##### rpcUrls?

```ts theme={null}
optional rpcUrls: Partial<Record<string, {
  rpcUrl: string;
}>>;
```

Defined in: [client.ts:87](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/client.ts#L87)

JSON-RPC endpoints used for payment signing, keyed by CAIP-2 network
identifier.

Base and Base Sepolia already resolve an RPC automatically via the
CDP-authenticated node endpoint, so no override is required for those.
Every other network (Polygon, Arbitrum, World, etc.) has no default and
must be supplied here to backfill optional EVM extension capabilities
(for example, `eip2612` gas-sponsoring enrichment).

Falls back to `CDP_X402_RPC_URLS` env var (JSON object mapping CAIP-2 IDs to URL strings).

***

### CdpX402WalletAddresses

Defined in: [client.ts:276](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/client.ts#L276)

Wallet addresses provisioned by a [CdpX402Client](/sdks/cdp-sdks-v2/typescript/x402/classes/CdpX402Client).

#### Properties

##### evmAddress

```ts theme={null}
evmAddress: `0x${string}`;
```

Defined in: [client.ts:278](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/client.ts#L278)

EVM address (EOA or Smart Contract Wallet) used for payment signing.

##### svmAddress

```ts theme={null}
svmAddress: string;
```

Defined in: [client.ts:280](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/client.ts#L280)

Solana address used for payment signing.

##### ownerWallet?

```ts theme={null}
optional ownerWallet: string;
```

Defined in: [client.ts:282](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/client.ts#L282)

Name of the owner EOA account backing a `"smart"` wallet, if configured.

***

### CdpFacilitatorClientArgs

Defined in: [facilitator.ts:114](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/facilitator.ts#L114)

Args for [createCdpFacilitatorClient](/sdks/cdp-sdks-v2/typescript/x402/functions/createCdpFacilitatorClient).

#### Properties

##### apiKeyId?

```ts theme={null}
optional apiKeyId: string;
```

Defined in: [facilitator.ts:118](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/facilitator.ts#L118)

CDP API key ID. Falls back to the `CDP_API_KEY_ID` environment variable.

##### apiKeySecret?

```ts theme={null}
optional apiKeySecret: string;
```

Defined in: [facilitator.ts:122](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/facilitator.ts#L122)

CDP API key secret. Falls back to the `CDP_API_KEY_SECRET` environment variable.

##### baseUrl?

```ts theme={null}
optional baseUrl: string;
```

Defined in: [facilitator.ts:139](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/facilitator.ts#L139)

Override the facilitator base URL. Defaults to the CDP production endpoint
(`https://api.cdp.coinbase.com/platform/v2/x402`).

The hostname and per-operation paths are derived from this URL, so JWT
signing is automatically bound to the correct host and paths. Use this
to point at a staging, canary, or local facilitator without changing
any other configuration.

###### Example

```typescript theme={null}
const facilitator = createCdpFacilitatorClient({
  baseUrl: "https://api.staging.cdp.coinbase.com/platform/v2/x402",
});
```

***

### SpendControlsRegistry

Defined in: [guardrails/apply.ts:52](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/guardrails/apply.ts#L52)

Settlement-aware finalization handlers attached to a client by [applySpendControls](/sdks/cdp-sdks-v2/typescript/x402/functions/applySpendControls).

#### Methods

##### confirm()

```ts theme={null}
confirm(paymentPayload: PaymentPayload): Promise<void>;
```

Defined in: [guardrails/apply.ts:58](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/guardrails/apply.ts#L58)

Mark a previously-created payment as settled on-chain.

###### Parameters

###### paymentPayload

`PaymentPayload`

The payment payload to confirm.

###### Returns

`Promise`\<`void`>

##### rollback()

```ts theme={null}
rollback(paymentPayload: PaymentPayload): Promise<void>;
```

Defined in: [guardrails/apply.ts:64](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/guardrails/apply.ts#L64)

Undo a previously-recorded provisional spend after the payment did not settle.

###### Parameters

###### paymentPayload

`PaymentPayload`

The payment payload to roll back.

###### Returns

`Promise`\<`void`>

***

### SpendStore

Defined in: [guardrails/types.ts:124](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/guardrails/types.ts#L124)

Storage interface for the spend ledger.

**The default implementation is in-memory and process-local.** For
production workloads where the cap must be enforced across restarts or
replicas, implement this interface against a shared durable backend (Redis,
Postgres, DynamoDB, etc.) and pass an instance via [SpendControls.store](/sdks/cdp-sdks-v2/typescript/x402/type-aliases/SpendControls#store).

#### Methods

##### size()?

```ts theme={null}
optional size(): Promise<number>;
```

Defined in: [guardrails/types.ts:126](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/guardrails/types.ts#L126)

* Optional: return the current entry count.

###### Returns

`Promise`\<`number`>

##### load()

```ts theme={null}
load(): Promise<SpendLedgerEntry[]>;
```

Defined in: [guardrails/types.ts:128](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/guardrails/types.ts#L128)

* Returns all entries currently held by the store.

###### Returns

`Promise`\<[`SpendLedgerEntry`](/sdks/cdp-sdks-v2/typescript/x402/type-aliases/SpendLedgerEntry)\[]>

##### append()

```ts theme={null}
append(entry: SpendLedgerEntry): Promise<void>;
```

Defined in: [guardrails/types.ts:130](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/guardrails/types.ts#L130)

* Adds a single entry to the store.

###### Parameters

###### entry

[`SpendLedgerEntry`](/sdks/cdp-sdks-v2/typescript/x402/type-aliases/SpendLedgerEntry)

###### Returns

`Promise`\<`void`>

##### prune()?

```ts theme={null}
optional prune(olderThanMs: number): Promise<void>;
```

Defined in: [guardrails/types.ts:132](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/guardrails/types.ts#L132)

* Optional: drop entries older than `olderThanMs`.

###### Parameters

###### olderThanMs

`number`

###### Returns

`Promise`\<`void`>

##### dropOldest()?

```ts theme={null}
optional dropOldest(n: number): Promise<void>;
```

Defined in: [guardrails/types.ts:134](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/guardrails/types.ts#L134)

* Optional: drop the oldest `n` entries.

###### Parameters

###### n

`number`

###### Returns

`Promise`\<`void`>

##### removeEntry()?

```ts theme={null}
optional removeEntry(entry: SpendLedgerEntry): Promise<void>;
```

Defined in: [guardrails/types.ts:136](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/guardrails/types.ts#L136)

* Optional: remove a specific entry by its field values.

###### Parameters

###### entry

[`SpendLedgerEntry`](/sdks/cdp-sdks-v2/typescript/x402/type-aliases/SpendLedgerEntry)

###### Returns

`Promise`\<`void`>

***

### SpendTrackerOptions

Defined in: [guardrails/spend-tracker.ts:17](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/guardrails/spend-tracker.ts#L17)

Constructor options for [SpendTracker](/sdks/cdp-sdks-v2/typescript/x402/classes/SpendTracker).

#### Properties

##### maxLedgerEntries?

```ts theme={null}
optional maxLedgerEntries: number;
```

Defined in: [guardrails/spend-tracker.ts:21](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/guardrails/spend-tracker.ts#L21)

Maximum number of entries to hold. Defaults to DEFAULT\_MAX\_LEDGER\_ENTRIES.

##### store?

```ts theme={null}
optional store: SpendStore;
```

Defined in: [guardrails/spend-tracker.ts:25](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/guardrails/spend-tracker.ts#L25)

Storage backend. Defaults to an in-memory array-backed store.

***

### RecordSpendInput

Defined in: [guardrails/spend-tracker.ts:31](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/guardrails/spend-tracker.ts#L31)

Argument shape for [SpendTracker.record](/sdks/cdp-sdks-v2/typescript/x402/classes/SpendTracker#record).

#### Properties

##### atomicAmount

```ts theme={null}
atomicAmount: bigint;
```

Defined in: [guardrails/spend-tracker.ts:33](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/guardrails/spend-tracker.ts#L33)

* Payment amount in base units.

##### asset

```ts theme={null}
asset: string;
```

Defined in: [guardrails/spend-tracker.ts:35](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/guardrails/spend-tracker.ts#L35)

* Asset identifier.

##### network

```ts theme={null}
network: `${string}:${string}`;
```

Defined in: [guardrails/spend-tracker.ts:37](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/guardrails/spend-tracker.ts#L37)

* Network the payment was made on.

##### payTo

```ts theme={null}
payTo: string;
```

Defined in: [guardrails/spend-tracker.ts:39](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/guardrails/spend-tracker.ts#L39)

* Payee address.

***

### TotalSpendQuery

Defined in: [guardrails/spend-tracker.ts:45](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/guardrails/spend-tracker.ts#L45)

Argument shape for [SpendTracker.total](/sdks/cdp-sdks-v2/typescript/x402/classes/SpendTracker#total).

#### Properties

##### asset

```ts theme={null}
asset: string;
```

Defined in: [guardrails/spend-tracker.ts:47](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/guardrails/spend-tracker.ts#L47)

* Asset to sum.

##### since?

```ts theme={null}
optional since: number;
```

Defined in: [guardrails/spend-tracker.ts:49](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/guardrails/spend-tracker.ts#L49)

* Inclusive lower bound (ms since epoch). Entries strictly older are excluded.

***

### CdpSmartAccount

Defined in: [account-signers.ts:39](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/account-signers.ts#L39)

The subset of a CDP Smart Account (EvmSmartAccount) required to sign x402
payments. Its `signTypedData` mirrors the SDK smart-account signature, which
requires a `network` derived from the EIP-712 domain's `chainId`.

#### Properties

##### address

```ts theme={null}
address: `0x${string}`;
```

Defined in: [account-signers.ts:40](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/account-signers.ts#L40)

#### Methods

##### signTypedData()

```ts theme={null}
signTypedData(options: Omit<SignTypedDataOptions, "address"> & {
  network: string;
}): Promise<`0x${string}`>;
```

Defined in: [account-signers.ts:41](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/account-signers.ts#L41)

###### Parameters

###### options

`Omit`\<`SignTypedDataOptions`, `"address"`> & \{
`network`: `string`;
}

###### Returns

`Promise`\<`` `0x${string}` ``>

***

### CdpSolanaAccount

Defined in: [account-signers.ts:97](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/account-signers.ts#L97)

Minimal interface for a CDP Solana account.
Matches the relevant methods from CdpClient's SolanaAccount.

#### Properties

##### address

```ts theme={null}
address: string;
```

Defined in: [account-signers.ts:98](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/account-signers.ts#L98)

#### Methods

##### signTransaction()

```ts theme={null}
signTransaction(options: {
  transaction: string;
}): Promise<{
  signedTransaction: string;
}>;
```

Defined in: [account-signers.ts:99](https://github.com/coinbase/cdp-sdk/blob/a1195adcfa5a93627bd3cb79831b188cc13073a1/typescript/packages/cdp-sdk/src/x402/account-signers.ts#L99)

###### Parameters

###### options

###### transaction

`string`

###### Returns

`Promise`\<\{
`signedTransaction`: `string`;
}>

## Type Aliases

* [CdpPaymentScheme](/sdks/cdp-sdks-v2/typescript/x402/type-aliases/CdpPaymentScheme)
* [PayToConfig](/sdks/cdp-sdks-v2/typescript/x402/type-aliases/PayToConfig)
* [WalletConfig](/sdks/cdp-sdks-v2/typescript/x402/type-aliases/WalletConfig)
* [ResolvedSpendControls](/sdks/cdp-sdks-v2/typescript/x402/type-aliases/ResolvedSpendControls)
* [SpendControls](/sdks/cdp-sdks-v2/typescript/x402/type-aliases/SpendControls)
* [SpendLedgerEntry](/sdks/cdp-sdks-v2/typescript/x402/type-aliases/SpendLedgerEntry)
* [Amount](/sdks/cdp-sdks-v2/typescript/x402/type-aliases/Amount)
* [Duration](/sdks/cdp-sdks-v2/typescript/x402/type-aliases/Duration)
* [Asset](/sdks/cdp-sdks-v2/typescript/x402/type-aliases/Asset)
* [Address](/sdks/cdp-sdks-v2/typescript/x402/type-aliases/Address)
* [SpendControlErrorCode](/sdks/cdp-sdks-v2/typescript/x402/type-aliases/SpendControlErrorCode)
* [SpendControlErrorDetails](/sdks/cdp-sdks-v2/typescript/x402/type-aliases/SpendControlErrorDetails)
* [CdpEvmAccount](/sdks/cdp-sdks-v2/typescript/x402/type-aliases/CdpEvmAccount)

## Variables

* [CDP\_SERVER\_DEFAULT\_EVM\_NETWORKS](/sdks/cdp-sdks-v2/typescript/x402/variables/CDP_SERVER_DEFAULT_EVM_NETWORKS)
* [CDP\_SERVER\_DEFAULT\_SVM\_NETWORKS](/sdks/cdp-sdks-v2/typescript/x402/variables/CDP_SERVER_DEFAULT_SVM_NETWORKS)
* [CDP\_SERVER\_DEFAULT\_NETWORKS](/sdks/cdp-sdks-v2/typescript/x402/variables/CDP_SERVER_DEFAULT_NETWORKS)
* [CDP\_SERVER\_DEVELOPMENT\_EVM\_NETWORKS](/sdks/cdp-sdks-v2/typescript/x402/variables/CDP_SERVER_DEVELOPMENT_EVM_NETWORKS)
* [CDP\_SERVER\_DEVELOPMENT\_SVM\_NETWORKS](/sdks/cdp-sdks-v2/typescript/x402/variables/CDP_SERVER_DEVELOPMENT_SVM_NETWORKS)
* [CDP\_SERVER\_DEVELOPMENT\_NETWORKS](/sdks/cdp-sdks-v2/typescript/x402/variables/CDP_SERVER_DEVELOPMENT_NETWORKS)
* [CDP\_EXTENSION\_GAS\_SPONSORING\_EIP2612](/sdks/cdp-sdks-v2/typescript/x402/variables/CDP_EXTENSION_GAS_SPONSORING_EIP2612)
* [CDP\_EXTENSION\_GAS\_SPONSORING\_ERC20\_APPROVAL](/sdks/cdp-sdks-v2/typescript/x402/variables/CDP_EXTENSION_GAS_SPONSORING_ERC20_APPROVAL)
* [CDP\_EXTENSION\_BAZAAR](/sdks/cdp-sdks-v2/typescript/x402/variables/CDP_EXTENSION_BAZAAR)
* [CDP\_SUPPORTED\_EXTENSIONS](/sdks/cdp-sdks-v2/typescript/x402/variables/CDP_SUPPORTED_EXTENSIONS)
* [CDP\_FACILITATOR\_URL](/sdks/cdp-sdks-v2/typescript/x402/variables/CDP_FACILITATOR_URL)
* [SpendControlErrorCodes](/sdks/cdp-sdks-v2/typescript/x402/variables/SpendControlErrorCodes)

## Functions

* [createX402Server](/sdks/cdp-sdks-v2/typescript/x402/functions/createX402Server)
* [getCdpDefaultSchemes](/sdks/cdp-sdks-v2/typescript/x402/functions/getCdpDefaultSchemes)
* [getCdpBatchSettlementScheme](/sdks/cdp-sdks-v2/typescript/x402/functions/getCdpBatchSettlementScheme)
* [getCdpExtensionRegistrations](/sdks/cdp-sdks-v2/typescript/x402/functions/getCdpExtensionRegistrations)
* [buildBazaarDeclaration](/sdks/cdp-sdks-v2/typescript/x402/functions/buildBazaarDeclaration)
* [createCdpFacilitatorClient](/sdks/cdp-sdks-v2/typescript/x402/functions/createCdpFacilitatorClient)
* [applySpendControls](/sdks/cdp-sdks-v2/typescript/x402/functions/applySpendControls)
* [getSpendControlsRegistry](/sdks/cdp-sdks-v2/typescript/x402/functions/getSpendControlsRegistry)
* [parseDuration](/sdks/cdp-sdks-v2/typescript/x402/functions/parseDuration)
* [parseAmount](/sdks/cdp-sdks-v2/typescript/x402/functions/parseAmount)
* [normalizeAsset](/sdks/cdp-sdks-v2/typescript/x402/functions/normalizeAsset)
* [normalizeNetwork](/sdks/cdp-sdks-v2/typescript/x402/functions/normalizeNetwork)
* [normalizePayee](/sdks/cdp-sdks-v2/typescript/x402/functions/normalizePayee)
* [fromCdpEvmAccount](/sdks/cdp-sdks-v2/typescript/x402/functions/fromCdpEvmAccount)
* [fromCdpSmartWallet](/sdks/cdp-sdks-v2/typescript/x402/functions/fromCdpSmartWallet)
* [cdpSolanaAccountToSvmSigner](/sdks/cdp-sdks-v2/typescript/x402/functions/cdpSolanaAccountToSvmSigner)
* [getDefaultEvmRpcUrls](/sdks/cdp-sdks-v2/typescript/x402/functions/getDefaultEvmRpcUrls)
