The Python SDK includes extensive examples demonstrating every feature of the CDP SDK with Pythonic async/await patterns and full type hints.
Setup
Get CDP Credentials
Get your CDP API key and wallet secret from the CDP Portal
Configure Environment
Copy .env.example to .env and add your credentials: cd examples/python
cp .env.example .env
Edit .env: CDP_API_KEY_ID = your_api_key_id
CDP_API_KEY_SECRET = your_api_key_secret
CDP_WALLET_SECRET = your_wallet_secret
Install Dependencies
The Python examples use uv for dependency management:
The Python SDK requires Python 3.9 or higher.
Running Examples
Run any example using uv run python:
uv run python path/to/example.py
For example:
uv run python evm/accounts/create_account.py
uv run python solana/transactions/account.sign_message.py
uv run python evm/swaps/account.swap.py
EVM Examples
Account Management
Create Account - Basic account creation
evm/accounts/create_account.py
# Usage: uv run python evm/accounts/create_account.py
import asyncio
from cdp import CdpClient
from dotenv import load_dotenv
load_dotenv()
async def main ():
async with CdpClient() as cdp:
account = await cdp.evm.create_account()
print ( f "Successfully created account: { account.address } " )
asyncio.run(main())
What it does:
Initializes the CDP client with credentials from environment variables
Creates a new EVM account
Prints the account address
Run: uv run python evm/accounts/create_account.py
Get or Create Account - Idempotent account creation
evm/accounts/get_or_create_account.py
import asyncio
from cdp import CdpClient
from dotenv import load_dotenv
load_dotenv()
async def main ():
async with CdpClient() as cdp:
# Will create account if it doesn't exist, or return existing
account = await cdp.evm.get_or_create_account( name = "my-app-account" )
print ( f "Account address: { account.address } " )
print ( f "Account name: { account.name } " )
asyncio.run(main())
Run: uv run python evm/accounts/get_or_create_account.py
Export & Import Account - Backup and restore accounts
evm/accounts/export_account.py
import asyncio
import json
from cdp import CdpClient
from dotenv import load_dotenv
load_dotenv()
async def main ():
async with CdpClient() as cdp:
account = await cdp.evm.create_account()
# Export account data (private key encrypted with wallet secret)
exported_data = await account.export()
print ( f "Exported account: { account.address } " )
print ( f "Encrypted data: { json.dumps(exported_data, indent = 2 ) } " )
# Save exported_data securely (e.g., encrypted storage)
asyncio.run(main())
evm/accounts/import_account.py
import asyncio
from cdp import CdpClient
from dotenv import load_dotenv
load_dotenv()
async def main ():
async with CdpClient() as cdp:
# Import previously exported account
account = await cdp.evm.import_account(
address = "0x..." ,
encrypted_private_key = "..." ,
)
print ( f "Imported account: { account.address } " )
asyncio.run(main())
Run:
uv run python evm/accounts/export_account.py
uv run python evm/accounts/import_account.py
Create Account with Policy - Account with spending restrictions
evm/accounts/create_account_with_policy.py
import asyncio
from cdp import CdpClient
from dotenv import load_dotenv
load_dotenv()
async def main ():
async with CdpClient() as cdp:
# Create a policy that restricts spending
policy = await cdp.evm.create_policy(
type = "usd_spend_restriction" ,
max_usd_per_period = "100.00" ,
period_seconds = 86400 , # 24 hours
)
# Create account with the policy
account = await cdp.evm.create_account(
name = "restricted-account" ,
policy_ids = [policy.id]
)
print ( f "Created account with policy: { account.address } " )
print ( f "Policy ID: { policy.id } " )
asyncio.run(main())
Run: uv run python evm/accounts/create_account_with_policy.py
Transactions
Transfer Tokens - Send ETH and ERC20 tokens
evm/transactions/transfer.py
import asyncio
from cdp import CdpClient
from dotenv import load_dotenv
load_dotenv()
async def main ():
async with CdpClient() as cdp:
sender = await cdp.evm.get_or_create_account( name = "Sender" )
receiver = await cdp.evm.get_or_create_account( name = "Receiver" )
# Request testnet funds
print ( "Requesting ETH from faucet..." )
faucet_result = await cdp.evm.request_faucet(
address = sender.address,
network = "base-sepolia" ,
token = "eth" ,
)
print ( f "Faucet tx: { faucet_result.transaction_hash } " )
# Transfer 0.001 ETH
print ( f "Transferring 0.001 ETH to { receiver.address } ..." )
result = await sender.transfer(
to = receiver.address,
amount = "1000000000000000" , # 0.001 ETH in wei
token = "eth" ,
network = "base-sepolia" ,
)
print ( f "Transfer successful: { result.transaction_hash } " )
print ( f "Explorer: https://sepolia.basescan.org/tx/ { result.transaction_hash } " )
asyncio.run(main())
Run: uv run python evm/transactions/transfer.py
Send Transaction - Custom transaction with Web3.py
evm/transactions/send_transaction.py
import asyncio
from cdp import CdpClient
from cdp.evm_transaction_types import TransactionRequestEIP1559
from dotenv import load_dotenv
from web3 import Web3
load_dotenv()
async def main ():
async with CdpClient() as cdp:
account = await cdp.evm.get_or_create_account( name = "Sender" )
# Create transaction
transaction = TransactionRequestEIP1559(
to = "0x0000000000000000000000000000000000000000" ,
value = Web3.to_wei( 0.001 , "ether" ),
gas = 21000 ,
)
# Send transaction
tx_hash = await account.send_transaction(
transaction = transaction,
network = "base-sepolia" ,
)
print ( f "Transaction sent: { tx_hash } " )
asyncio.run(main())
Run: uv run python evm/transactions/send_transaction.py
Sign Typed Data - EIP-712 structured data signing
evm/transactions/sign_typed_data.py
import asyncio
from cdp import CdpClient
from dotenv import load_dotenv
load_dotenv()
async def main ():
async with CdpClient() as cdp:
account = await cdp.evm.create_account()
# EIP-712 typed data
typed_data = {
"domain" : {
"name" : "My DApp" ,
"version" : "1" ,
"chainId" : 84532 ,
},
"types" : {
"Person" : [
{ "name" : "name" , "type" : "string" },
{ "name" : "wallet" , "type" : "address" },
],
},
"primaryType" : "Person" ,
"message" : {
"name" : "Alice" ,
"wallet" : "0x1234567890123456789012345678901234567890" ,
},
}
signature = await account.sign_typed_data(typed_data)
print ( f "Signature: { signature } " )
asyncio.run(main())
Run: uv run python evm/transactions/sign_typed_data.py
Token Swaps
Swap Tokens - Complete swap example with token approvals
evm/swaps/account.swap.py
# Usage: uv run python evm/swaps/account.swap.py
import asyncio
from decimal import Decimal
from cdp import CdpClient
from cdp.actions.evm.swap import AccountSwapOptions
from cdp.utils import parse_units
from dotenv import load_dotenv
from web3 import Web3
load_dotenv()
# Network configuration
NETWORK = "base" # Base mainnet
# Token definitions
TOKENS = {
"WETH" : {
"address" : "0x4200000000000000000000000000000000000006" ,
"symbol" : "WETH" ,
"decimals" : 18 ,
},
"USDC" : {
"address" : "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" ,
"symbol" : "USDC" ,
"decimals" : 6 ,
},
}
async def main ():
"""Execute a token swap with automatic approvals."""
print ( f "Note: Using { NETWORK } network" )
async with CdpClient() as cdp:
# Get or create an account
account = await cdp.evm.get_or_create_account( name = "SwapAccount" )
print ( f "Using account: { account.address } " )
try :
from_token = TOKENS [ "WETH" ]
to_token = TOKENS [ "USDC" ]
# Swap 0.1 WETH for USDC
from_amount = parse_units( "0.1" , from_token[ "decimals" ])
print ( f " \n Swapping 0.1 { from_token[ 'symbol' ] } for { to_token[ 'symbol' ] } " )
# Execute swap
result = await account.swap(
AccountSwapOptions(
network = NETWORK ,
from_token = from_token[ "address" ],
to_token = to_token[ "address" ],
from_amount = from_amount,
slippage_bps = 100 , # 1% slippage tolerance
)
)
print ( f " \n ✅ Swap submitted successfully!" )
print ( f "Transaction hash: { result.transaction_hash } " )
print ( f "🔗 View on explorer: https://basescan.org/tx/ { result.transaction_hash } " )
except Exception as error:
if "Insufficient liquidity" in str (error):
print ( " \n ❌ Swap failed: Insufficient liquidity" )
else :
raise error
if __name__ == "__main__" :
asyncio.run(main())
What it does:
Creates or retrieves an account
Swaps 0.1 WETH for USDC on Base mainnet
Handles token approvals automatically
Includes 1% slippage tolerance
Returns transaction hash
Run: uv run python evm/swaps/account.swap.py
Quote Swap - Get swap price before executing
evm/swaps/account.quote_swap.py
import asyncio
from decimal import Decimal
from cdp import CdpClient
from cdp.utils import parse_units
from dotenv import load_dotenv
load_dotenv()
async def main ():
async with CdpClient() as cdp:
account = await cdp.evm.get_or_create_account( name = "Quoter" )
# Get quote for swapping ETH to USDC
quote = await account.quote_swap(
from_token = "eth" ,
to_token = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" , # USDC
from_amount = parse_units( "0.1" , 18 ),
network = "base" ,
slippage_bps = 100 ,
)
# Check liquidity
if not quote.liquidity_available:
print ( "❌ Insufficient liquidity for this swap" )
return
# Display quote details
to_amount = Decimal(quote.to_amount) / Decimal( 10 ** 6 ) # USDC has 6 decimals
min_to_amount = Decimal(quote.min_to_amount) / Decimal( 10 ** 6 )
print ( f "Quote: 0.1 ETH = { to_amount :.2f} USDC" )
print ( f "Minimum received: { min_to_amount :.2f} USDC" )
# Execute if price is acceptable
result = await quote.execute()
print ( f "Swap executed: { result.transaction_hash } " )
asyncio.run(main())
Run: uv run python evm/swaps/account.quote_swap.py
Get Swap Price - Check price without account
evm/swaps/get_swap_price.py
import asyncio
from decimal import Decimal
from cdp import CdpClient
from cdp.utils import parse_units
from dotenv import load_dotenv
load_dotenv()
async def main ():
async with CdpClient() as cdp:
# Get swap price without an account
price = await cdp.evm.get_swap_price(
from_token = "eth" ,
to_token = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" , # USDC
from_amount = parse_units( "1" , 18 ), # 1 ETH
network = "base" ,
)
to_amount = Decimal(price.to_amount) / Decimal( 10 ** 6 )
print ( f "Current price: 1 ETH = { to_amount :.2f} USDC" )
asyncio.run(main())
Run: uv run python evm/swaps/get_swap_price.py
Smart Accounts
Create and Use Smart Account - EIP-4337 account abstraction
evm/smart-accounts/send_user_operation.py
import asyncio
from cdp import CdpClient
from dotenv import load_dotenv
from web3 import Web3
load_dotenv()
async def main ():
async with CdpClient() as cdp:
# Create an owner account
owner = await cdp.evm.get_or_create_account( name = "Owner" )
# Create a smart account
smart_account = await cdp.evm.create_smart_account(
owners = [owner.address],
name = "my-smart-account" ,
)
print ( f "Smart account created: { smart_account.address } " )
# Fund the smart account
print ( "Funding smart account..." )
await cdp.evm.request_faucet(
address = smart_account.address,
network = "base-sepolia" ,
token = "eth" ,
)
# Send a user operation
result = await cdp.evm.prepare_and_send_user_operation(
address = smart_account.address,
network = "base-sepolia" ,
calls = [
{
"to" : "0x0000000000000000000000000000000000000000" ,
"value" : Web3.to_wei( 0.000001 , "ether" ),
"data" : "0x" ,
}
],
)
print ( f "User operation hash: { result.user_op_hash } " )
print ( f "View on Blockscout: https://base-sepolia.blockscout.com/op/ { result.user_op_hash } " )
asyncio.run(main())
Run: uv run python evm/smart-accounts/send_user_operation.py
Smart Account with Server Account Owner
evm/smart-accounts/send_user_operation_with_server_account_owner.py
import asyncio
from cdp import CdpClient
from dotenv import load_dotenv
from web3 import Web3
load_dotenv()
async def main ():
"""Demonstrates creating a smart account with a server-managed owner."""
async with CdpClient() as cdp:
# Server accounts are managed by CDP - you don't need to store keys
owner = await cdp.evm.create_account( name = "ServerManagedOwner" )
# Create smart account with server-managed owner
smart_account = await cdp.evm.create_smart_account(
owners = [owner.address]
)
print ( f "Smart account: { smart_account.address } " )
print ( f "Owner (server-managed): { owner.address } " )
# The server automatically signs user operations
result = await cdp.evm.prepare_and_send_user_operation(
address = smart_account.address,
network = "base-sepolia" ,
calls = [{
"to" : "0x0000000000000000000000000000000000000000" ,
"value" : "1000000000000000" ,
"data" : "0x" ,
}],
)
print ( f "User operation sent: { result.user_op_hash } " )
asyncio.run(main())
Run: uv run python evm/smart-accounts/send_user_operation_with_server_account_owner.py
Policies
Create USD Spend Restriction Policy
evm/policies/create_usd_spend_restriction_policy.py
import asyncio
from cdp import CdpClient
from dotenv import load_dotenv
load_dotenv()
async def main ():
async with CdpClient() as cdp:
# Create a policy that limits spending to $100 per day
policy = await cdp.evm.create_policy(
type = "usd_spend_restriction" ,
max_usd_per_period = "100.00" ,
period_seconds = 86400 , # 24 hours
description = "Daily spending limit" ,
)
print ( f "Policy created: { policy.id } " )
print ( f "Max spend: $ { policy.max_usd_per_period } per { policy.period_seconds } s" )
asyncio.run(main())
Run: uv run python evm/policies/create_usd_spend_restriction_policy.py
evm/policies/apply_policy_to_account.py
import asyncio
from cdp import CdpClient
from dotenv import load_dotenv
load_dotenv()
async def main ():
async with CdpClient() as cdp:
# Create policy
policy = await cdp.evm.create_policy(
type = "usd_spend_restriction" ,
max_usd_per_period = "50.00" ,
period_seconds = 3600 , # 1 hour
)
# Create account
account = await cdp.evm.create_account( name = "restricted-account" )
# Apply policy to account
await account.apply_policy(policy.id)
print ( f "Applied policy { policy.id } to account { account.address } " )
asyncio.run(main())
Run: uv run python evm/policies/apply_policy_to_account.py
Solana Examples
Account Management
solana/accounts/create_account.py
import asyncio
from cdp import CdpClient
from dotenv import load_dotenv
load_dotenv()
async def main ():
async with CdpClient() as cdp:
account = await cdp.solana.create_account()
print ( f "Created Solana account: { account.address } " )
asyncio.run(main())
Run: uv run python solana/accounts/create_account.py
solana/transactions/account.transfer.py
import asyncio
from cdp import CdpClient
from dotenv import load_dotenv
load_dotenv()
async def main ():
async with CdpClient() as cdp:
sender = await cdp.solana.get_or_create_account( name = "Sender" )
receiver = await cdp.solana.get_or_create_account( name = "Receiver" )
# Request SOL from faucet
print ( "Requesting SOL from faucet..." )
await sender.request_faucet()
# Transfer 0.01 SOL (9 decimals)
print ( f "Transferring 0.01 SOL to { receiver.address } ..." )
result = await sender.transfer(
to = receiver.address,
amount = 10000000 , # 0.01 SOL
)
print ( f "Transfer signature: { result.signature } " )
asyncio.run(main())
Run: uv run python solana/transactions/account.transfer.py
solana/transactions/account.sign_message.py
import asyncio
from cdp import CdpClient
from dotenv import load_dotenv
load_dotenv()
async def main ():
async with CdpClient() as cdp:
account = await cdp.solana.create_account()
message = "Hello from CDP SDK on Solana!"
signature = await account.sign_message(message)
print ( f "Message: { message } " )
print ( f "Signature: { signature } " )
asyncio.run(main())
Run: uv run python solana/transactions/account.sign_message.py
Web3.py Integration
The CDP SDK integrates with Web3.py for advanced Ethereum development:
Use CDP Account with Web3.py
evm/ecosystem/web3py/send_transaction_with_web3.py
import asyncio
from cdp import CdpClient
from dotenv import load_dotenv
from web3 import Web3
load_dotenv()
async def main ():
async with CdpClient() as cdp:
account = await cdp.evm.create_account()
# Convert CDP account to Web3 account
web3_account = account.to_web3_account()
# Use with Web3.py
w3 = Web3(Web3.HTTPProvider( "https://sepolia.base.org" ))
transaction = {
"to" : "0x0000000000000000000000000000000000000000" ,
"value" : w3.to_wei( 0.001 , "ether" ),
"gas" : 21000 ,
"gasPrice" : w3.eth.gas_price,
"nonce" : w3.eth.get_transaction_count(web3_account.address),
"chainId" : 84532 ,
}
# Sign and send with Web3.py
signed_tx = web3_account.sign_transaction(transaction)
tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
print ( f "Transaction hash: { tx_hash.hex() } " )
asyncio.run(main())
Run: uv run python evm/ecosystem/web3py/send_transaction_with_web3.py
End User Management
end_user/create_end_user.py
import asyncio
from cdp import CdpClient
from dotenv import load_dotenv
load_dotenv()
async def main ():
async with CdpClient() as cdp:
# Create an end user
end_user = await cdp.create_end_user(
external_id = "user-123" ,
metadata = { "email" : "[email protected] " },
)
print ( f "End user created: { end_user.id } " )
print ( f "External ID: { end_user.external_id } " )
asyncio.run(main())
Run: uv run python end_user/create_end_user.py
end_user/add_end_user_evm_account.py
import asyncio
from cdp import CdpClient
from dotenv import load_dotenv
load_dotenv()
async def main ():
async with CdpClient() as cdp:
# Get or create end user
end_user = await cdp.get_or_create_end_user(
external_id = "user-123"
)
# Add EVM account to end user
account = await end_user.add_evm_account(
name = "user-wallet"
)
print ( f "Added account { account.address } to end user { end_user.id } " )
asyncio.run(main())
Run: uv run python end_user/add_end_user_evm_account.py
Full Example List
View all examples in the repository:
Browse Python Examples View all Python examples on GitHub
Next Steps
Python SDK Reference Explore the full Python SDK API
TypeScript Examples See TypeScript examples
Rust Examples View Rust examples
Go Examples Check Go examples